ReactOS 0.4.17-dev-1190-g4c812f4
usp10.c File Reference
#include <stdarg.h>
#include <stdlib.h>
#include <math.h>
#include "windef.h"
#include "winbase.h"
#include "ntgdi.h"
#include "ntuser.h"
#include "winerror.h"
#include "winuser.h"
#include "winnls.h"
#include "winreg.h"
#include "usp10.h"
#include "usp10_internal.h"
#include "wine/debug.h"
Include dependency graph for usp10.c:

Go to the source code of this file.

Classes

struct  usp10_script_range
 
struct  StringGlyphs
 
struct  StringAnalysis
 
struct  FindGlyph_struct
 

Macros

#define Numeric_space   0x0020
 
#define ZWSP   0x200B
 
#define ZWNJ   0x200C
 
#define ZWJ   0x200D
 

Enumerations

enum  stringanalysis_flags { SCRIPT_STRING_ANALYSIS_FLAGS_SIZE = 0x1 , SCRIPT_STRING_ANALYSIS_FLAGS_INVALID = 0x2 }
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (uniscribe)
 
BOOL usp10_array_reserve (void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size)
 
static BOOL set_cache_font_properties (const HDC hdc, ScriptCache *sc)
 
static void get_cache_font_properties (SCRIPT_FONTPROPERTIES *sfp, ScriptCache *sc)
 
static LONG get_cache_height (SCRIPT_CACHE *psc)
 
static BYTE get_cache_pitch_family (SCRIPT_CACHE *psc)
 
static WORD get_cache_glyph (SCRIPT_CACHE *psc, DWORD c)
 
static WORD set_cache_glyph (SCRIPT_CACHE *psc, WCHAR c, WORD glyph)
 
static BOOL get_cache_glyph_widths (SCRIPT_CACHE *psc, WORD glyph, ABC *abc)
 
static BOOL set_cache_glyph_widths (SCRIPT_CACHE *psc, WORD glyph, ABC *abc)
 
static HRESULT init_script_cache (const HDC hdc, SCRIPT_CACHE *psc)
 
static WCHAR mirror_char (WCHAR ch)
 
static DWORD decode_surrogate_pair (const WCHAR *str, unsigned int index, unsigned int end)
 
static int __cdecl usp10_compare_script_range (const void *key, const void *value)
 
static enum usp10_script get_char_script (const WCHAR *str, unsigned int index, unsigned int end, unsigned int *consumed)
 
static int __cdecl compare_FindGlyph (const void *a, const void *b)
 
int USP10_FindGlyphInLogClust (const WORD *pwLogClust, int cChars, WORD target)
 
HRESULT WINAPI ScriptFreeCache (SCRIPT_CACHE *psc)
 
HRESULT WINAPI ScriptGetProperties (const SCRIPT_PROPERTIES ***props, int *num)
 
HRESULT WINAPI ScriptGetFontProperties (HDC hdc, SCRIPT_CACHE *psc, SCRIPT_FONTPROPERTIES *sfp)
 
HRESULT WINAPI ScriptRecordDigitSubstitution (LCID locale, SCRIPT_DIGITSUBSTITUTE *sds)
 
HRESULT WINAPI ScriptApplyDigitSubstitution (const SCRIPT_DIGITSUBSTITUTE *sds, SCRIPT_CONTROL *sc, SCRIPT_STATE *ss)
 
static BOOL is_indic (enum usp10_script script)
 
static enum usp10_script base_indic (enum usp10_script script)
 
static BOOL script_is_numeric (enum usp10_script script)
 
static HRESULT _ItemizeInternal (const WCHAR *pwcInChars, int cInChars, int cMaxItems, const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState, SCRIPT_ITEM *pItems, OPENTYPE_TAG *pScriptTags, int *pcItems)
 
HRESULT WINAPI ScriptItemizeOpenType (const WCHAR *pwcInChars, int cInChars, int cMaxItems, const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState, SCRIPT_ITEM *pItems, OPENTYPE_TAG *pScriptTags, int *pcItems)
 
HRESULT WINAPI ScriptItemize (const WCHAR *pwcInChars, int cInChars, int cMaxItems, const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState, SCRIPT_ITEM *pItems, int *pcItems)
 
static int getGivenTabWidth (ScriptCache *psc, SCRIPT_TABDEF *pTabdef, int charPos, int current_x)
 
static BOOL requires_fallback (HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, const WCHAR *pwcInChars, int cChars)
 
static void find_fallback_font (enum usp10_script scriptid, WCHAR *FaceName)
 
HRESULT WINAPI ScriptStringAnalyse (HDC hdc, const void *pString, int cString, int cGlyphs, int iCharset, DWORD dwFlags, int iReqWidth, SCRIPT_CONTROL *psControl, SCRIPT_STATE *psState, const int *piDx, SCRIPT_TABDEF *pTabdef, const BYTE *pbInClass, SCRIPT_STRING_ANALYSIS *pssa)
 
static BOOL does_glyph_start_cluster (const SCRIPT_VISATTR *pva, const WORD *pwLogClust, int cChars, int glyph, int direction)
 
static HRESULT SS_ItemOut (SCRIPT_STRING_ANALYSIS ssa, int iX, int iY, int iItem, int cStart, int cEnd, UINT uOptions, const RECT *prc, BOOL fSelected, BOOL fDisabled)
 
HRESULT WINAPI ScriptStringOut (SCRIPT_STRING_ANALYSIS ssa, int iX, int iY, UINT uOptions, const RECT *prc, int iMinSel, int iMaxSel, BOOL fDisabled)
 
HRESULT WINAPI ScriptStringCPtoX (SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrailing, int *pX)
 
HRESULT WINAPI ScriptStringXtoCP (SCRIPT_STRING_ANALYSIS ssa, int iX, int *piCh, int *piTrailing)
 
HRESULT WINAPI ScriptStringFree (SCRIPT_STRING_ANALYSIS *pssa)
 
static int get_cluster_size (const WORD *pwLogClust, int cChars, int item, int direction, int *iCluster, int *check_out)
 
static int get_glyph_cluster_advance (const int *piAdvance, const SCRIPT_VISATTR *pva, const WORD *pwLogClust, int cGlyphs, int cChars, int glyph, int direction)
 
HRESULT WINAPI ScriptCPtoX (int iCP, BOOL fTrailing, int cChars, int cGlyphs, const WORD *pwLogClust, const SCRIPT_VISATTR *psva, const int *piAdvance, const SCRIPT_ANALYSIS *psa, int *piX)
 
static BOOL get_cluster_data (const WORD *pwLogClust, int cChars, int cluster_index, int *cluster_size, int *start_index)
 
static int get_cluster_advance (const int *piAdvance, const SCRIPT_VISATTR *psva, const WORD *pwLogClust, int cGlyphs, int cChars, int cluster, int direction)
 
HRESULT WINAPI ScriptXtoCP (int iX, int cChars, int cGlyphs, const WORD *pwLogClust, const SCRIPT_VISATTR *psva, const int *piAdvance, const SCRIPT_ANALYSIS *psa, int *piCP, int *piTrailing)
 
HRESULT WINAPI ScriptBreak (const WCHAR *chars, int count, const SCRIPT_ANALYSIS *sa, SCRIPT_LOGATTR *la)
 
HRESULT WINAPI ScriptIsComplex (const WCHAR *chars, int len, DWORD flag)
 
HRESULT WINAPI ScriptShapeOpenType (HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, OPENTYPE_TAG tagLangSys, int *rcRangeChars, TEXTRANGE_PROPERTIES **rpRangeProperties, int cRanges, const WCHAR *pwcChars, int cChars, int cMaxGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProps, WORD *pwOutGlyphs, SCRIPT_GLYPHPROP *pOutGlyphProps, int *pcGlyphs)
 
HRESULT WINAPI ScriptShape (HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, int cChars, int cMaxGlyphs, SCRIPT_ANALYSIS *psa, WORD *pwOutGlyphs, WORD *pwLogClust, SCRIPT_VISATTR *psva, int *pcGlyphs)
 
HRESULT WINAPI ScriptPlaceOpenType (HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, OPENTYPE_TAG tagLangSys, int *rcRangeChars, TEXTRANGE_PROPERTIES **rpRangeProperties, int cRanges, const WCHAR *pwcChars, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProps, int cChars, const WORD *pwGlyphs, const SCRIPT_GLYPHPROP *pGlyphProps, int cGlyphs, int *piAdvance, GOFFSET *pGoffset, ABC *pABC)
 
HRESULT WINAPI ScriptPlace (HDC hdc, SCRIPT_CACHE *psc, const WORD *pwGlyphs, int cGlyphs, const SCRIPT_VISATTR *psva, SCRIPT_ANALYSIS *psa, int *piAdvance, GOFFSET *pGoffset, ABC *pABC)
 
HRESULT WINAPI ScriptGetCMap (HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcInChars, int cChars, DWORD dwFlags, WORD *pwOutGlyphs)
 
HRESULT WINAPI ScriptTextOut (const HDC hdc, SCRIPT_CACHE *psc, int x, int y, UINT fuOptions, const RECT *lprc, const SCRIPT_ANALYSIS *psa, const WCHAR *pwcReserved, int iReserved, const WORD *pwGlyphs, int cGlyphs, const int *piAdvance, const int *piJustify, const GOFFSET *pGoffset)
 
HRESULT WINAPI ScriptCacheGetHeight (HDC hdc, SCRIPT_CACHE *psc, LONG *height)
 
HRESULT WINAPI ScriptGetGlyphABCWidth (HDC hdc, SCRIPT_CACHE *psc, WORD glyph, ABC *abc)
 
HRESULT WINAPI ScriptLayout (int runs, const BYTE *level, int *vistolog, int *logtovis)
 
HRESULT WINAPI ScriptStringGetLogicalWidths (SCRIPT_STRING_ANALYSIS ssa, int *piDx)
 
HRESULT WINAPI ScriptStringValidate (SCRIPT_STRING_ANALYSIS ssa)
 
const SIZE *WINAPI ScriptString_pSize (SCRIPT_STRING_ANALYSIS ssa)
 
const SCRIPT_LOGATTR *WINAPI ScriptString_pLogAttr (SCRIPT_STRING_ANALYSIS ssa)
 
const int *WINAPI ScriptString_pcOutChars (SCRIPT_STRING_ANALYSIS ssa)
 
HRESULT WINAPI ScriptStringGetOrder (SCRIPT_STRING_ANALYSIS ssa, UINT *order)
 
HRESULT WINAPI ScriptGetLogicalWidths (const SCRIPT_ANALYSIS *sa, int nbchars, int nbglyphs, const int *advances, const WORD *log_clust, const SCRIPT_VISATTR *sva, int *widths)
 
HRESULT WINAPI ScriptApplyLogicalWidth (const int *dx, int num_chars, int num_glyphs, const WORD *log_clust, const SCRIPT_VISATTR *sva, const int *advance, const SCRIPT_ANALYSIS *sa, ABC *abc, int *justify)
 
HRESULT WINAPI ScriptJustify (const SCRIPT_VISATTR *sva, const int *advance, int num_glyphs, int dx, int min_kashida, int *justify)
 
HRESULT WINAPI ScriptGetFontScriptTags (HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags)
 
HRESULT WINAPI ScriptGetFontLanguageTags (HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, int cMaxTags, OPENTYPE_TAG *pLangSysTags, int *pcTags)
 
HRESULT WINAPI ScriptGetFontFeatureTags (HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, OPENTYPE_TAG tagLangSys, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags)
 
HRESULT WINAPI ScriptGetFontAlternateGlyphs (HDC hdc, SCRIPT_CACHE *sc, SCRIPT_ANALYSIS *sa, OPENTYPE_TAG tag_script, OPENTYPE_TAG tag_langsys, OPENTYPE_TAG tag_feature, WORD id, int size, WORD *list, int *count)
 

Variables

static const struct usp10_script_range script_ranges []
 
const scriptData scriptInformation []
 
static const SCRIPT_PROPERTIES * script_props []
 
static CRITICAL_SECTION cs_script_cache = { &cs_script_cache_dbg, -1, 0, 0, 0, 0 }
 
static CRITICAL_SECTION_DEBUG cs_script_cache_dbg
 
static struct list script_cache_list = LIST_INIT(script_cache_list)
 

Macro Definition Documentation

◆ Numeric_space

#define Numeric_space   0x0020

◆ ZWJ

#define ZWJ   0x200D

◆ ZWNJ

#define ZWNJ   0x200C

◆ ZWSP

#define ZWSP   0x200B

Enumeration Type Documentation

◆ stringanalysis_flags

Enumerator
SCRIPT_STRING_ANALYSIS_FLAGS_SIZE 
SCRIPT_STRING_ANALYSIS_FLAGS_INVALID 

Definition at line 629 of file usp10.c.

630{
633};
@ SCRIPT_STRING_ANALYSIS_FLAGS_SIZE
Definition: usp10.c:631
@ SCRIPT_STRING_ANALYSIS_FLAGS_INVALID
Definition: usp10.c:632

Function Documentation

◆ _ItemizeInternal()

static HRESULT _ItemizeInternal ( const WCHAR *  pwcInChars,
int  cInChars,
int  cMaxItems,
const SCRIPT_CONTROL *  psControl,
const SCRIPT_STATE *  psState,
SCRIPT_ITEM *  pItems,
OPENTYPE_TAG *  pScriptTags,
int *  pcItems 
)
static

Definition at line 1316 of file usp10.c.

1320{
1321
1322#define Numeric_space 0x0020
1323#define ZWSP 0x200B
1324#define ZWNJ 0x200C
1325#define ZWJ 0x200D
1326
1327 enum usp10_script last_indic = Script_Undefined;
1328 int cnt = 0, index = 0, str = 0;
1329 enum usp10_script New_Script = -1;
1330 int i;
1331 WORD *levels = NULL;
1332 WORD *layout_levels = NULL;
1333 WORD *overrides = NULL;
1334 WORD *strength = NULL;
1335 enum usp10_script *scripts;
1336 WORD baselevel = 0;
1337 WORD baselayout = 0;
1338 BOOL new_run;
1339 WORD layoutRTL = 0;
1340 BOOL forceLevels = FALSE;
1341 unsigned int consumed = 0;
1343
1344 TRACE("%s,%d,%d,%p,%p,%p,%p\n", debugstr_wn(pwcInChars, cInChars), cInChars, cMaxItems,
1345 psControl, psState, pItems, pcItems);
1346
1347 if (!pwcInChars || !cInChars || !pItems || cMaxItems < 2)
1348 return E_INVALIDARG;
1349
1350 if (!(scripts = calloc(cInChars, sizeof(*scripts))))
1351 return E_OUTOFMEMORY;
1352
1353 for (i = 0; i < cInChars; i++)
1354 {
1355 if (!consumed)
1356 {
1357 scripts[i] = get_char_script(pwcInChars,i,cInChars,&consumed);
1358 consumed --;
1359 }
1360 else
1361 {
1362 scripts[i] = scripts[i-1];
1363 consumed --;
1364 }
1365 /* Devanagari danda (U+0964) and double danda (U+0965) are used for
1366 all Indic scripts */
1367 if ((pwcInChars[i] == 0x964 || pwcInChars[i] ==0x965) && last_indic != Script_Undefined)
1368 scripts[i] = last_indic;
1369 else if (is_indic(scripts[i]))
1370 last_indic = base_indic(scripts[i]);
1371
1372 /* Some unicode points :
1373 (Zero Width Space U+200B - Right-to-Left Mark U+200F)
1374 (Left Right Embed U+202A - Left Right Override U+202D)
1375 (Left Right Isolate U+2066 - Pop Directional Isolate U+2069)
1376 will force us into bidi mode */
1377 if (!forceLevels && ((pwcInChars[i] >= 0x200B && pwcInChars[i] <= 0x200F) ||
1378 (pwcInChars[i] >= 0x202A && pwcInChars[i] <= 0x202E) ||
1379 (pwcInChars[i] >= 0x2066 && pwcInChars[i] <= 0x2069)))
1380
1381 forceLevels = TRUE;
1382
1383 /* Diacritical marks merge with other scripts */
1384 if (scripts[i] == Script_Diacritical)
1385 {
1386 if (i > 0)
1387 {
1388 if (pScriptTags)
1389 scripts[i] = scripts[i-1];
1390 else
1391 {
1392 int j;
1393 BOOL asian = FALSE;
1394 enum usp10_script first_script = scripts[i-1];
1395 for (j = i-1; j >= 0 && scripts[j] == first_script && pwcInChars[j] != Numeric_space; j--)
1396 {
1397 enum usp10_script original = scripts[j];
1398 if (original == Script_Ideograph || original == Script_Kana || original == Script_Yi || original == Script_CJK_Han || original == Script_Bopomofo)
1399 {
1400 asian = TRUE;
1401 break;
1402 }
1403 if (original != Script_MathAlpha && scriptInformation[scripts[j]].props.fComplex)
1404 break;
1405 scripts[j] = scripts[i];
1406 if (original == Script_Punctuation2)
1407 break;
1408 }
1409 if (j >= 0 && (scriptInformation[scripts[j]].props.fComplex || asian))
1410 scripts[i] = scripts[j];
1411 }
1412 }
1413 }
1414 }
1415
1416 for (i = 0; i < cInChars; i++)
1417 {
1418 /* Joiners get merged preferencially right */
1419 if (i > 0 && (pwcInChars[i] == ZWJ || pwcInChars[i] == ZWNJ || pwcInChars[i] == ZWSP))
1420 {
1421 int j;
1422 if (i+1 == cInChars)
1423 scripts[i] = scripts[i-1];
1424 else
1425 {
1426 for (j = i+1; j < cInChars; j++)
1427 {
1428 if (pwcInChars[j] != ZWJ && pwcInChars[j] != ZWNJ
1429 && pwcInChars[j] != ZWSP && pwcInChars[j] != Numeric_space)
1430 {
1431 scripts[i] = scripts[j];
1432 break;
1433 }
1434 }
1435 }
1436 }
1437 }
1438
1439 if (psState && psControl)
1440 {
1441 if (!(levels = calloc(cInChars, sizeof(*levels))))
1442 goto nomemory;
1443
1444 if (!(overrides = calloc(cInChars, sizeof(*overrides))))
1445 goto nomemory;
1446
1447 if (!(layout_levels = calloc(cInChars, sizeof(*layout_levels))))
1448 goto nomemory;
1449
1450 if (psState->fOverrideDirection)
1451 {
1452 if (!forceLevels)
1453 {
1454 SCRIPT_STATE s = *psState;
1456 BIDI_DetermineLevels(pwcInChars, cInChars, &s, psControl, layout_levels, overrides);
1457 if (odd(layout_levels[0]))
1458 forceLevels = TRUE;
1459 else for (i = 0; i < cInChars; i++)
1460 if (layout_levels[i]!=layout_levels[0])
1461 {
1462 forceLevels = TRUE;
1463 break;
1464 }
1465 }
1466
1467 BIDI_DetermineLevels(pwcInChars, cInChars, psState, psControl, levels, overrides);
1468 }
1469 else
1470 {
1471 BIDI_DetermineLevels(pwcInChars, cInChars, psState, psControl, levels, overrides);
1472 memcpy(layout_levels, levels, cInChars * sizeof(WORD));
1473 }
1474 baselevel = levels[0];
1475 baselayout = layout_levels[0];
1476 for (i = 0; i < cInChars; i++)
1477 if (levels[i]!=levels[0])
1478 break;
1479 if (i >= cInChars && !odd(baselevel) && !odd(psState->uBidiLevel) && !forceLevels)
1480 {
1481 free(levels);
1482 free(overrides);
1483 free(layout_levels);
1484 overrides = NULL;
1485 levels = NULL;
1486 layout_levels = NULL;
1487 }
1488 else
1489 {
1490 if (!(strength = calloc(cInChars, sizeof(*strength))))
1491 goto nomemory;
1492 BIDI_GetStrengths(pwcInChars, cInChars, psControl, strength);
1493
1494 /* We currently mis-level leading Diacriticals */
1495 if (scripts[0] == Script_Diacritical)
1496 for (i = 0; i < cInChars && scripts[0] == Script_Diacritical; i++)
1497 {
1498 levels[i] = odd(levels[i])?levels[i]+1:levels[i];
1499 strength[i] = BIDI_STRONG;
1500 }
1501
1502 /* Math punctuation bordered on both sides by numbers can be
1503 merged into the number */
1504 for (i = 0; i < cInChars; i++)
1505 {
1506 if (i > 0 && i < cInChars-1 &&
1507 script_is_numeric(scripts[i-1]) &&
1508 wcschr(L"#$%+,-./:\x2212\x2044\x00a0", pwcInChars[i]))
1509 {
1510 if (script_is_numeric(scripts[i+1]))
1511 {
1512 scripts[i] = scripts[i+1];
1513 levels[i] = levels[i-1];
1514 strength[i] = strength[i-1];
1515 i++;
1516 }
1517 else if (wcschr(L"#$%+-/\x2212\x2044", pwcInChars[i]))
1518 {
1519 int j;
1520 for (j = i+1; j < cInChars; j++)
1521 {
1522 if (script_is_numeric(scripts[j]))
1523 {
1524 for(;i<j; i++)
1525 {
1526 scripts[i] = scripts[j];
1527 levels[i] = levels[i-1];
1528 strength[i] = strength[i-1];
1529 }
1530 }
1531 else if (pwcInChars[i] != pwcInChars[j]) break;
1532 }
1533 }
1534 }
1535 }
1536
1537 for (i = 0; i < cInChars; i++)
1538 {
1539 /* Numerics at level 0 get bumped to level 2 */
1540 if (!overrides[i] && (levels[i] == 0 || (odd(psState->uBidiLevel)
1541 && levels[i] == psState->uBidiLevel + 1)) && script_is_numeric(scripts[i]))
1542 {
1543 levels[i] = 2;
1544 }
1545
1546 /* Joiners get merged preferencially right */
1547 if (i > 0 && (pwcInChars[i] == ZWJ || pwcInChars[i] == ZWNJ || pwcInChars[i] == ZWSP))
1548 {
1549 int j;
1550 if (i+1 == cInChars && levels[i-1] == levels[i])
1551 strength[i] = strength[i-1];
1552 else
1553 for (j = i+1; j < cInChars && levels[i] == levels[j]; j++)
1554 if (pwcInChars[j] != ZWJ && pwcInChars[j] != ZWNJ
1555 && pwcInChars[j] != ZWSP && pwcInChars[j] != Numeric_space)
1556 {
1557 strength[i] = strength[j];
1558 break;
1559 }
1560 }
1561 }
1562 if (psControl->fMergeNeutralItems)
1563 {
1564 /* Merge the neutrals */
1565 for (i = 0; i < cInChars; i++)
1566 {
1567 if (strength[i] == BIDI_NEUTRAL || strength[i] == BIDI_WEAK)
1568 {
1569 int j;
1570 for (j = i; j > 0; j--)
1571 {
1572 if (levels[i] != levels[j])
1573 break;
1574 if ((strength[j] == BIDI_STRONG) || (strength[i] == BIDI_NEUTRAL && strength[j] == BIDI_WEAK))
1575 {
1576 scripts[i] = scripts[j];
1577 strength[i] = strength[j];
1578 break;
1579 }
1580 }
1581 }
1582 /* Try going the other way */
1583 if (strength[i] == BIDI_NEUTRAL || strength[i] == BIDI_WEAK)
1584 {
1585 int j;
1586 for (j = i; j < cInChars; j++)
1587 {
1588 if (levels[i] != levels[j])
1589 break;
1590 if ((strength[j] == BIDI_STRONG) || (strength[i] == BIDI_NEUTRAL && strength[j] == BIDI_WEAK))
1591 {
1592 scripts[i] = scripts[j];
1593 strength[i] = strength[j];
1594 break;
1595 }
1596 }
1597 }
1598 }
1599 }
1600 }
1601 }
1602
1603 while ((!levels || (levels && cnt+1 < cInChars && levels[cnt+1] == levels[0]))
1604 && (cnt < cInChars && pwcInChars[cnt] == Numeric_space))
1605 cnt++;
1606
1607 if (cnt == cInChars) /* All Spaces */
1608 {
1609 cnt = 0;
1610 New_Script = scripts[cnt];
1611 }
1612
1613 pItems[index].iCharPos = 0;
1614 pItems[index].a = scriptInformation[scripts[cnt]].a;
1615 if (pScriptTags)
1616 pScriptTags[index] = scriptInformation[scripts[cnt]].scriptTag;
1617
1618 if (strength && strength[cnt] == BIDI_STRONG)
1619 str = strength[cnt];
1620 else if (strength)
1621 str = strength[0];
1622
1623 cnt = 0;
1624
1625 if (levels)
1626 {
1627 if (strength[cnt] == BIDI_STRONG)
1628 layoutRTL = odd(layout_levels[cnt]);
1629 else
1630 layoutRTL = (psState->uBidiLevel || odd(layout_levels[cnt]));
1631 if (overrides)
1632 pItems[index].a.s.fOverrideDirection = (overrides[cnt] != 0);
1633 pItems[index].a.fRTL = odd(levels[cnt]);
1634 if (script_is_numeric(pItems[index].a.eScript))
1635 pItems[index].a.fLayoutRTL = layoutRTL;
1636 else
1637 pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
1638 pItems[index].a.s.uBidiLevel = levels[cnt];
1639 }
1640 else if (!pItems[index].a.s.uBidiLevel || (overrides && overrides[cnt]))
1641 {
1642 if (pItems[index].a.s.uBidiLevel != baselevel)
1643 pItems[index].a.s.fOverrideDirection = TRUE;
1644 layoutRTL = odd(baselayout);
1645 pItems[index].a.s.uBidiLevel = baselevel;
1646 pItems[index].a.fRTL = odd(baselevel);
1647 if (script_is_numeric(pItems[index].a.eScript))
1648 pItems[index].a.fLayoutRTL = odd(baselayout);
1649 else
1650 pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
1651 }
1652
1653 TRACE("New_Level=%i New_Strength=%i New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n",
1654 levels?levels[cnt]:-1, str, New_Script, pItems[index].a.eScript, index, cnt,
1655 pItems[index].iCharPos);
1656
1657 for (cnt=1; cnt < cInChars; cnt++)
1658 {
1659 if(pwcInChars[cnt] != Numeric_space)
1660 New_Script = scripts[cnt];
1661 else if (levels)
1662 {
1663 int j = 1;
1664 while (cnt + j < cInChars - 1 && pwcInChars[cnt+j] == Numeric_space && levels[cnt] == levels[cnt+j])
1665 j++;
1666 if (cnt + j < cInChars && levels[cnt] == levels[cnt+j])
1667 New_Script = scripts[cnt+j];
1668 else
1669 New_Script = scripts[cnt];
1670 }
1671
1672 new_run = FALSE;
1673 /* merge space strengths*/
1674 if (strength && strength[cnt] == BIDI_STRONG && str != BIDI_STRONG && New_Script == pItems[index].a.eScript)
1675 str = BIDI_STRONG;
1676
1677 if (strength && strength[cnt] == BIDI_NEUTRAL && str == BIDI_STRONG && pwcInChars[cnt] != Numeric_space && New_Script == pItems[index].a.eScript)
1678 str = BIDI_NEUTRAL;
1679
1680 /* changes in level */
1681 if (levels && (levels[cnt] != pItems[index].a.s.uBidiLevel))
1682 {
1683 TRACE("Level break(%i/%i)\n",pItems[index].a.s.uBidiLevel,levels[cnt]);
1684 new_run = TRUE;
1685 }
1686 /* changes in strength */
1687 else if (strength && pwcInChars[cnt] != Numeric_space && str != strength[cnt])
1688 {
1689 TRACE("Strength break (%i/%i)\n",str,strength[cnt]);
1690 new_run = TRUE;
1691 }
1692 /* changes in script */
1693 else if (((pwcInChars[cnt] != Numeric_space) && (New_Script != -1) && (New_Script != pItems[index].a.eScript)) || (New_Script == Script_Control))
1694 {
1695 TRACE("Script break(%i/%i)\n",pItems[index].a.eScript,New_Script);
1696 new_run = TRUE;
1697 }
1698
1699 if (!new_run && strength && str == BIDI_STRONG)
1700 {
1701 layoutRTL = odd(layout_levels[cnt]);
1702 if (script_is_numeric(pItems[index].a.eScript))
1703 pItems[index].a.fLayoutRTL = layoutRTL;
1704 }
1705
1706 if (new_run)
1707 {
1708 TRACE("New_Level = %i, New_Strength = %i, New_Script=%d, eScript=%d\n", levels?levels[cnt]:-1, strength?strength[cnt]:str, New_Script, pItems[index].a.eScript);
1709
1710 index++;
1711 if (index+1 > cMaxItems)
1712 goto nomemory;
1713
1714 if (strength)
1715 str = strength[cnt];
1716
1717 pItems[index].iCharPos = cnt;
1718 memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
1719
1720 pItems[index].a = scriptInformation[New_Script].a;
1721 if (pScriptTags)
1722 pScriptTags[index] = scriptInformation[New_Script].scriptTag;
1723 if (levels)
1724 {
1725 if (overrides)
1726 pItems[index].a.s.fOverrideDirection = (overrides[cnt] != 0);
1727 if (layout_levels[cnt] == 0)
1728 layoutRTL = 0;
1729 else
1730 layoutRTL = (layoutRTL || odd(layout_levels[cnt]));
1731 pItems[index].a.fRTL = odd(levels[cnt]);
1732 if (script_is_numeric(pItems[index].a.eScript))
1733 pItems[index].a.fLayoutRTL = layoutRTL;
1734 else
1735 pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
1736 pItems[index].a.s.uBidiLevel = levels[cnt];
1737 }
1738 else if (!pItems[index].a.s.uBidiLevel || (overrides && overrides[cnt]))
1739 {
1740 if (pItems[index].a.s.uBidiLevel != baselevel)
1741 pItems[index].a.s.fOverrideDirection = TRUE;
1742 pItems[index].a.s.uBidiLevel = baselevel;
1743 pItems[index].a.fRTL = odd(baselevel);
1744 if (script_is_numeric(pItems[index].a.eScript))
1745 pItems[index].a.fLayoutRTL = layoutRTL;
1746 else
1747 pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
1748 }
1749
1750 TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos);
1751 }
1752 }
1753
1754 /* While not strictly necessary according to the spec, make sure the n+1
1755 * item is set up to prevent random behaviour if the caller erroneously
1756 * checks the n+1 structure */
1757 index++;
1758 if (index + 1 > cMaxItems) goto nomemory;
1759 memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
1760
1761 TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos);
1762
1763 /* Set one SCRIPT_STATE item being returned */
1764 if (pcItems) *pcItems = index;
1765
1766 /* Set SCRIPT_ITEM */
1767 pItems[index].iCharPos = cnt; /* the last item contains the ptr to the lastchar */
1768 res = S_OK;
1769nomemory:
1770 free(levels);
1771 free(overrides);
1772 free(layout_levels);
1773 free(strength);
1774 free(scripts);
1775 return res;
1776}
#define index(s, c)
Definition: various.h:29
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define free
Definition: debug_ros.c:5
#define odd(x)
Definition: bidi.c:60
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define wcschr
Definition: compat.h:17
int consumed
Definition: scanf.h:200
static BOOL script_is_numeric(enum usp10_script script)
Definition: usp10.c:1311
static BOOL is_indic(enum usp10_script script)
Definition: usp10.c:1277
static enum usp10_script base_indic(enum usp10_script script)
Definition: usp10.c:1282
const scriptData scriptInformation[]
Definition: usp10.c:312
static enum usp10_script get_char_script(const WCHAR *str, unsigned int index, unsigned int end, unsigned int *consumed)
Definition: usp10.c:941
#define Numeric_space
#define ZWJ
#define ZWSP
#define ZWNJ
#define L(x)
Definition: resources.c:13
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
GLdouble s
Definition: gl.h:2039
GLuint res
Definition: glext.h:9613
GLuint index
Definition: glext.h:6031
GLsizei levels
Definition: glext.h:7884
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define S_OK
Definition: intsafe.h:52
#define debugstr_wn
Definition: kernel32.h:33
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define calloc
Definition: rosglue.h:14
const WCHAR * str
@ Script_Yi
Definition: scripts.h:101
@ Script_Bopomofo
Definition: scripts.h:16
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
OPENTYPE_TAG scriptTag
SCRIPT_ANALYSIS a
SCRIPT_STATE s
Definition: usp10.h:146
DWORD fMergeNeutralItems
Definition: usp10.h:102
SCRIPT_ANALYSIS a
Definition: usp10.h:151
int iCharPos
Definition: usp10.h:150
WORD fOverrideDirection
Definition: usp10.h:126
WORD uBidiLevel
Definition: usp10.h:125
usp10_script
@ Script_Undefined
@ Script_Diacritical
@ Script_Punctuation2
@ Script_Control
@ Script_Ideograph
@ Script_Kana
@ Script_CJK_Han
@ Script_MathAlpha
#define BIDI_NEUTRAL
#define BIDI_STRONG
#define BIDI_WEAK
static const WCHAR props[]
Definition: wbemdisp.c:288
_In_ size_t cnt
Definition: wcstombs.cpp:43
BOOL BIDI_DetermineLevels(const WCHAR *lpString, unsigned int uCount, const SCRIPT_STATE *s, const SCRIPT_CONTROL *c, WORD *lpOutLevels, WORD *lpOutOverrides)
Definition: bidi.c:1087
BOOL BIDI_GetStrengths(const WCHAR *string, unsigned int count, const SCRIPT_CONTROL *c, WORD *strength)
Definition: bidi.c:1248

Referenced by ScriptItemize(), and ScriptItemizeOpenType().

◆ base_indic()

static enum usp10_script base_indic ( enum usp10_script  script)
inlinestatic

Definition at line 1282 of file usp10.c.

1283{
1284 switch (script)
1285 {
1286 case Script_Devanagari:
1288 case Script_Bengali:
1291 case Script_Gurmukhi:
1293 case Script_Gujarati:
1296 case Script_Oriya:
1298 case Script_Tamil:
1300 case Script_Telugu:
1302 case Script_Kannada:
1304 case Script_Malayalam:
1306 default:
1307 return Script_Undefined;
1308 };
1309}
script
Definition: msipriv.h:396
@ Script_Telugu
Definition: scripts.h:94
@ Script_Bengali
Definition: scripts.h:15
@ Script_Oriya
Definition: scripts.h:75
@ Script_Kannada
Definition: scripts.h:49
@ Script_Gurmukhi
Definition: scripts.h:38
@ Script_Tamil
Definition: scripts.h:93
@ Script_Gujarati
Definition: scripts.h:37
@ Script_Devanagari
Definition: scripts.h:30
@ Script_Malayalam
Definition: scripts.h:62
@ Script_Kannada_Numeric
@ Script_Bengali_Numeric
@ Script_Gurmukhi_Numeric
@ Script_Devanagari_Numeric
@ Script_Telugu_Numeric
@ Script_Malayalam_Numeric
@ Script_Gujarati_Numeric
@ Script_Tamil_Numeric
@ Script_Oriya_Numeric
@ Script_Bengali_Currency
@ Script_Gujarati_Currency

Referenced by _ItemizeInternal().

◆ compare_FindGlyph()

static int __cdecl compare_FindGlyph ( const void *  a,
const void *  b 
)
static

Definition at line 999 of file usp10.c.

1000{
1002 const WORD *idx= (WORD*)b;
1003 int rc = 0;
1004
1005 if ( find->target > *idx)
1006 rc = 1;
1007 else if (find->target < *idx)
1008 rc = -1;
1009
1010 if (!find->ascending)
1011 rc *= -1;
1012 return rc;
1013}
static TAGID TAGID find
Definition: db.cpp:156
unsigned int idx
Definition: utils.c:40
GLboolean GLboolean GLboolean b
Definition: glext.h:6204

Referenced by USP10_FindGlyphInLogClust().

◆ decode_surrogate_pair()

static DWORD decode_surrogate_pair ( const WCHAR *  str,
unsigned int  index,
unsigned int  end 
)
static

Definition at line 918 of file usp10.c.

919{
920 if (index < end-1 && IS_SURROGATE_PAIR(str[index],str[index+1]))
921 {
922 DWORD ch = 0x10000 + ((str[index] - 0xd800) << 10) + (str[index+1] - 0xdc00);
923 TRACE("Surrogate Pair %x %x => %lx\n",str[index], str[index+1], ch);
924 return ch;
925 }
926 return 0;
927}
unsigned char ch[4][2]
Definition: console.c:118
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint end
Definition: gl.h:1545
#define IS_SURROGATE_PAIR(high, low)
Definition: winnls.h:765

Referenced by get_char_script(), and ScriptShapeOpenType().

◆ does_glyph_start_cluster()

static BOOL does_glyph_start_cluster ( const SCRIPT_VISATTR *  pva,
const WORD *  pwLogClust,
int  cChars,
int  glyph,
int  direction 
)
inlinestatic

Definition at line 2194 of file usp10.c.

2195{
2196 if (pva[glyph].fClusterStart)
2197 return TRUE;
2198 if (USP10_FindGlyphInLogClust(pwLogClust, cChars, glyph) >= 0)
2199 return TRUE;
2200
2201 return FALSE;
2202}
int USP10_FindGlyphInLogClust(const WORD *pwLogClust, int cChars, WORD target)
Definition: usp10.c:1015
_In_ INT _In_ INT cChars
Definition: winddi.h:1486

Referenced by get_glyph_cluster_advance(), and SS_ItemOut().

◆ find_fallback_font()

static void find_fallback_font ( enum usp10_script  scriptid,
WCHAR *  FaceName 
)
static

Definition at line 1930 of file usp10.c.

1931{
1932 HKEY hkey;
1933
1934 if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Uniscribe\\Fallback", &hkey))
1935 {
1936 WCHAR value[10];
1937 DWORD count = LF_FACESIZE * sizeof(WCHAR);
1938 DWORD type;
1939
1940 swprintf(value, ARRAY_SIZE(value), L"%x", scriptInformation[scriptid].scriptTag);
1941 if (RegQueryValueExW(hkey, value, 0, &type, (BYTE *)FaceName, &count))
1942 lstrcpyW(FaceName,scriptInformation[scriptid].fallbackFont);
1943 RegCloseKey(hkey);
1944 }
1945 else
1946 lstrcpyW(FaceName,scriptInformation[scriptid].fallbackFont);
1947}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define RegCloseKey(hKey)
Definition: registry.h:49
#define LF_FACESIZE
Definition: dimm.idl:39
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3234
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define lstrcpyW
Definition: compat.h:749
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
short WCHAR
Definition: pedump.c:58
Definition: pdh_main.c:64
#define swprintf
Definition: winemm.h:209
#define HKEY_CURRENT_USER
Definition: winreg.h:11
unsigned char BYTE
Definition: xxhash.c:193

Referenced by ScriptStringAnalyse().

◆ get_cache_font_properties()

static void get_cache_font_properties ( SCRIPT_FONTPROPERTIES *  sfp,
ScriptCache *  sc 
)
inlinestatic

Definition at line 733 of file usp10.c.

734{
735 *sfp = sc->sfp;
736}
SCRIPT_FONTPROPERTIES sfp

Referenced by ScriptGetFontProperties().

◆ get_cache_glyph()

static WORD get_cache_glyph ( SCRIPT_CACHE *  psc,
DWORD  c 
)
inlinestatic

Definition at line 748 of file usp10.c.

749{
750 CacheGlyphPage *page = ((ScriptCache *)*psc)->page[c / 0x10000];
751 WORD *block;
752
753 if (!page) return 0;
754 block = page->glyphs[(c % 0x10000) >> GLYPH_BLOCK_SHIFT];
755 if (!block) return 0;
756 return block[(c % 0x10000) & GLYPH_BLOCK_MASK];
757}
#define GLYPH_BLOCK_SHIFT
#define GLYPH_BLOCK_MASK
const GLubyte * c
Definition: glext.h:8905
Definition: module.h:576
static unsigned int block
Definition: xmlmemory.c:101

Referenced by ScriptGetCMap(), and ScriptShapeOpenType().

◆ get_cache_glyph_widths()

static BOOL get_cache_glyph_widths ( SCRIPT_CACHE *  psc,
WORD  glyph,
ABC *  abc 
)
inlinestatic

Definition at line 770 of file usp10.c.

771{
772 static const ABC nil;
773 ABC *block = ((ScriptCache *)*psc)->widths[glyph >> GLYPH_BLOCK_SHIFT];
774
775 if (!block || !memcmp(&block[glyph & GLYPH_BLOCK_MASK], &nil, sizeof(ABC))) return FALSE;
776 memcpy(abc, &block[glyph & GLYPH_BLOCK_MASK], sizeof(ABC));
777 return TRUE;
778}
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
#define nil
Definition: compat.h:23
Definition: wingdi.h:1856

Referenced by ScriptGetGlyphABCWidth(), and ScriptPlaceOpenType().

◆ get_cache_height()

static LONG get_cache_height ( SCRIPT_CACHE *  psc)
inlinestatic

Definition at line 738 of file usp10.c.

739{
740 return ((ScriptCache *)*psc)->tm.tmHeight;
741}

Referenced by ScriptCacheGetHeight().

◆ get_cache_pitch_family()

static BYTE get_cache_pitch_family ( SCRIPT_CACHE *  psc)
inlinestatic

Definition at line 743 of file usp10.c.

744{
745 return ((ScriptCache *)*psc)->tm.tmPitchAndFamily;
746}

Referenced by ScriptGetGlyphABCWidth(), and ScriptPlaceOpenType().

◆ get_char_script()

static enum usp10_script get_char_script ( const WCHAR *  str,
unsigned int  index,
unsigned int  end,
unsigned int *  consumed 
)
static

Definition at line 941 of file usp10.c.

943{
945 WORD type = 0, type2 = 0;
946 DWORD ch;
947
948 *consumed = 1;
949
950 if (str[index] == 0xc || str[index] == 0x20 || str[index] == 0x202f)
951 return Script_CR;
952
953 /* These punctuation characters are separated out as Latin punctuation */
954 if (wcschr(L"#$&',;<>?@\\^_`{|}~\x00a0", str[index]))
955 return Script_Punctuation2;
956
957 /* These chars are itemized as Punctuation by Windows */
958 if (str[index] == 0x2212 || str[index] == 0x2044)
959 return Script_Punctuation;
960
961 /* Currency Symbols by Unicode point */
962 switch (str[index])
963 {
964 case 0x09f2:
965 case 0x09f3: return Script_Bengali_Currency;
966 case 0x0af1: return Script_Gujarati_Currency;
967 case 0x0e3f: return Script_Thai_Currency;
968 case 0x20aa: return Script_Hebrew_Currency;
969 case 0x20ab: return Script_Vietnamese_Currency;
970 case 0xfb29: return Script_Hebrew_Currency;
971 }
972
974 GetStringTypeW(CT_CTYPE2, &str[index], 1, &type2);
975
976 if (type == 0)
977 return SCRIPT_UNDEFINED;
978
979 if (type & C1_CNTRL)
980 return Script_Control;
981
983 if (ch)
984 *consumed = 2;
985 else
986 ch = str[index];
987
991
992 if (range->numericScript && (type & C1_DIGIT || type2 == C2_ARABICNUMBER))
993 return range->numericScript;
994 if (range->punctScript && type & C1_PUNCT)
995 return range->punctScript;
996 return range->script;
997}
range
Definition: d3dx9_private.h:58
BOOL WINAPI GetStringTypeW(DWORD type, LPCWSTR src, INT count, LPWORD chartype)
Definition: locale.c:3098
static const struct usp10_script_range script_ranges[]
static DWORD decode_surrogate_pair(const WCHAR *str, unsigned int index, unsigned int end)
Definition: usp10.c:918
static int __cdecl usp10_compare_script_range(const void *key, const void *value)
Definition: usp10.c:929
#define C1_CNTRL
Definition: unicode.h:36
#define C1_DIGIT
Definition: unicode.h:33
#define C1_PUNCT
Definition: unicode.h:35
#define bsearch
#define SCRIPT_UNDEFINED
Definition: usp10.h:69
@ Script_Vietnamese_Currency
@ Script_CR
@ Script_Thai_Currency
@ Script_Hebrew_Currency
@ Script_Surrogates
@ Script_Punctuation
#define C2_ARABICNUMBER
Definition: winnls.h:283
#define CT_CTYPE2
Definition: winnls.h:266
#define CT_CTYPE1
Definition: winnls.h:265

Referenced by _ItemizeInternal(), and ScriptIsComplex().

◆ get_cluster_advance()

static int get_cluster_advance ( const int *  piAdvance,
const SCRIPT_VISATTR *  psva,
const WORD *  pwLogClust,
int  cGlyphs,
int  cChars,
int  cluster,
int  direction 
)
inlinestatic

Definition at line 2797 of file usp10.c.

2801{
2802 int glyph_start;
2803 int glyph_end;
2804 int i, advance;
2805
2806 if (direction > 0)
2807 i = 0;
2808 else
2809 i = (cChars - 1);
2810
2811 for (glyph_start = -1, glyph_end = -1; i < cChars && i >= 0 && (glyph_start < 0 || glyph_end < 0); i+=direction)
2812 {
2813 if (glyph_start < 0 && pwLogClust[i] != cluster) continue;
2814 if (pwLogClust[i] == cluster && glyph_start < 0) glyph_start = pwLogClust[i];
2815 if (glyph_start >= 0 && glyph_end < 0 && pwLogClust[i] != cluster) glyph_end = pwLogClust[i];
2816 }
2817 if (glyph_end < 0)
2818 {
2819 if (direction > 0)
2820 glyph_end = cGlyphs;
2821 else
2822 {
2823 /* Don't fully understand multi-glyph reversed clusters yet,
2824 * do they occur for real or just in our test? */
2825 FIXME("multi-glyph reversed clusters found\n");
2826 glyph_end = glyph_start + 1;
2827 }
2828 }
2829
2830 /* Check for fClusterStart, finding this generally would mean a malformed set of data */
2831 for (i = glyph_start+1; i< glyph_end; i++)
2832 {
2833 if (psva[i].fClusterStart)
2834 {
2835 glyph_end = i;
2836 break;
2837 }
2838 }
2839
2840 for (advance = 0, i = glyph_start; i < glyph_end; i++)
2841 advance += piAdvance[i];
2842
2843 return advance;
2844}
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
#define FIXME(fmt,...)
Definition: precomp.h:53
direction
Definition: netio.c:882
_In_ FONTOBJ _In_ ULONG _In_ ULONG cGlyphs
Definition: winddi.h:3799

Referenced by ScriptXtoCP().

◆ get_cluster_data()

static BOOL get_cluster_data ( const WORD *  pwLogClust,
int  cChars,
int  cluster_index,
int *  cluster_size,
int *  start_index 
)
inlinestatic

Definition at line 2764 of file usp10.c.

2765{
2766 int size = 0;
2767 int i;
2768
2769 for (i = 0; i < cChars; i++)
2770 {
2771 if (pwLogClust[i] == cluster_index)
2772 {
2773 if (!size && start_index)
2774 {
2775 *start_index = i;
2776 if (!cluster_size)
2777 return TRUE;
2778 }
2779 size++;
2780 }
2781 else if (size) break;
2782 }
2783 if (cluster_size)
2784 *cluster_size = size;
2785
2786 return (size > 0);
2787}
GLsizeiptr size
Definition: glext.h:5919
__u8 cluster_size
Definition: mkdosfs.c:4

Referenced by ScriptXtoCP().

◆ get_cluster_size()

static int get_cluster_size ( const WORD *  pwLogClust,
int  cChars,
int  item,
int  direction,
int *  iCluster,
int *  check_out 
)
inlinestatic

Definition at line 2598 of file usp10.c.

2600{
2601 int clust_size = 1;
2602 int check;
2603 WORD clust = pwLogClust[item];
2604
2605 for (check = item+direction; check < cChars && check >= 0; check+=direction)
2606 {
2607 if (pwLogClust[check] == clust)
2608 {
2609 clust_size ++;
2610 if (iCluster && *iCluster == -1)
2611 *iCluster = item;
2612 }
2613 else break;
2614 }
2615
2616 if (check_out)
2617 *check_out = check;
2618
2619 return clust_size;
2620}
#define check(expected, result)
Definition: dplayx.c:43

Referenced by ScriptCPtoX(), ScriptGetLogicalWidths(), and ScriptStringGetLogicalWidths().

◆ get_glyph_cluster_advance()

static int get_glyph_cluster_advance ( const int *  piAdvance,
const SCRIPT_VISATTR *  pva,
const WORD *  pwLogClust,
int  cGlyphs,
int  cChars,
int  glyph,
int  direction 
)
inlinestatic

Definition at line 2622 of file usp10.c.

2623{
2624 int advance;
2625 int log_clust_max;
2626
2627 advance = piAdvance[glyph];
2628
2629 if (pwLogClust[0] > pwLogClust[cChars-1])
2630 log_clust_max = pwLogClust[0];
2631 else
2632 log_clust_max = pwLogClust[cChars-1];
2633
2634 if (glyph > log_clust_max)
2635 return advance;
2636
2637 for (glyph+=direction; glyph < cGlyphs && glyph >= 0; glyph +=direction)
2638 {
2639
2640 if (does_glyph_start_cluster(pva, pwLogClust, cChars, glyph, direction))
2641 break;
2642 if (glyph > log_clust_max)
2643 break;
2644 advance += piAdvance[glyph];
2645 }
2646
2647 return advance;
2648}
static BOOL does_glyph_start_cluster(const SCRIPT_VISATTR *pva, const WORD *pwLogClust, int cChars, int glyph, int direction)
Definition: usp10.c:2194

Referenced by ScriptCPtoX(), ScriptGetLogicalWidths(), and ScriptStringGetLogicalWidths().

◆ getGivenTabWidth()

static int getGivenTabWidth ( ScriptCache *  psc,
SCRIPT_TABDEF *  pTabdef,
int  charPos,
int  current_x 
)
inlinestatic

Definition at line 1829 of file usp10.c.

1830{
1831 int defWidth;
1832 int cTabStops=0;
1833 INT *lpTabPos = NULL;
1834 INT nTabOrg = 0;
1835 INT x = 0;
1836
1837 if (pTabdef)
1838 lpTabPos = pTabdef->pTabStops;
1839
1840 if (pTabdef && pTabdef->iTabOrigin)
1841 {
1842 if (pTabdef->iScale)
1843 nTabOrg = (pTabdef->iTabOrigin * pTabdef->iScale)/4;
1844 else
1845 nTabOrg = pTabdef->iTabOrigin * psc->tm.tmAveCharWidth;
1846 }
1847
1848 if (pTabdef)
1849 cTabStops = pTabdef->cTabStops;
1850
1851 if (cTabStops == 1)
1852 {
1853 if (pTabdef->iScale)
1854 defWidth = ((pTabdef->pTabStops[0])*pTabdef->iScale) / 4;
1855 else
1856 defWidth = (pTabdef->pTabStops[0])*psc->tm.tmAveCharWidth;
1857 cTabStops = 0;
1858 }
1859 else
1860 {
1861 if (pTabdef->iScale)
1862 defWidth = (32 * pTabdef->iScale) / 4;
1863 else
1864 defWidth = 8 * psc->tm.tmAveCharWidth;
1865 }
1866
1867 for (; cTabStops>0 ; lpTabPos++, cTabStops--)
1868 {
1869 int position = *lpTabPos;
1870 if (position < 0)
1871 position = -1 * position;
1872 if (pTabdef->iScale)
1873 position = (position * pTabdef->iScale) / 4;
1874 else
1875 position = position * psc->tm.tmAveCharWidth;
1876
1877 if( nTabOrg + position > current_x)
1878 {
1879 if( position >= 0)
1880 {
1881 /* a left aligned tab */
1882 x = (nTabOrg + position) - current_x;
1883 break;
1884 }
1885 else
1886 {
1887 FIXME("Negative tabstop\n");
1888 break;
1889 }
1890 }
1891 }
1892 if ((!cTabStops) && (defWidth > 0))
1893 x =((((current_x - nTabOrg) / defWidth)+1) * defWidth) - current_x;
1894 else if ((!cTabStops) && (defWidth < 0))
1895 FIXME("TODO: Negative defWidth\n");
1896
1897 return x;
1898}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
TEXTMETRICW tm
LONG tmAveCharWidth
Definition: wingdi.h:2834
int * pTabStops
Definition: usp10.h:173
int32_t INT
Definition: typedefs.h:58

Referenced by ScriptStringAnalyse().

◆ init_script_cache()

static HRESULT init_script_cache ( const HDC  hdc,
SCRIPT_CACHE *  psc 
)
static

Definition at line 789 of file usp10.c.

790{
791 ScriptCache *sc;
792#ifdef __REACTOS__
793 ScriptCache *new_sc;
794#endif
795 unsigned size;
796 LOGFONTW lf;
797
798 if (!psc) return E_INVALIDARG;
799 if (*psc) return S_OK;
800 if (!hdc) return E_PENDING;
801
802 if (!GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf))
803 {
804 return E_INVALIDARG;
805 }
806 /* Ensure canonical result by zeroing extra space in lfFaceName */
808 memset(lf.lfFaceName + size, 0, sizeof(lf.lfFaceName) - size * sizeof(WCHAR));
809
812 {
813 if (!memcmp(&sc->lf, &lf, sizeof(lf)))
814 {
815 sc->refcount++;
817 *psc = sc;
818 return S_OK;
819 }
820 }
822
823#ifdef __REACTOS__
824 if (!(new_sc = calloc(1, sizeof(ScriptCache)))) return E_OUTOFMEMORY;
825 if (!GetTextMetricsW(hdc, &new_sc->tm))
826 {
827 free(new_sc);
828 return E_INVALIDARG;
829 }
831 if (size)
832 {
833 new_sc->otm = malloc(size);
834 new_sc->otm->otmSize = size;
836 }
837 new_sc->sfnt = (NtGdiGetFontData(hdc, MS_MAKE_TAG('h','e','a','d'), 0, NULL, 0) != GDI_ERROR);
838 if (!set_cache_font_properties(hdc, new_sc))
839 {
840 free(new_sc);
841 return E_INVALIDARG;
842 }
843 new_sc->lf = lf;
844 new_sc->refcount = 1;
845 *psc = new_sc;
846#else
847 if (!(sc = calloc(1, sizeof(ScriptCache)))) return E_OUTOFMEMORY;
848 if (!GetTextMetricsW(hdc, &sc->tm))
849 {
850 free(sc);
851 return E_INVALIDARG;
852 }
854 if (size)
855 {
856 sc->otm = malloc(size);
857 sc->otm->otmSize = size;
859 }
860 sc->sfnt = (NtGdiGetFontData(hdc, MS_MAKE_TAG('h','e','a','d'), 0, NULL, 0) != GDI_ERROR);
862 {
863 free(sc);
864 return E_INVALIDARG;
865 }
866 sc->lf = lf;
867 sc->refcount = 1;
868 *psc = sc;
869#endif
870
872#ifdef __REACTOS__
874#else
876#endif
878 {
879#ifdef __REACTOS__
880 if (sc != new_sc && !memcmp(&sc->lf, &lf, sizeof(lf)))
881#else
882 if (sc != *psc && !memcmp(&sc->lf, &lf, sizeof(lf)))
883#endif
884 {
885 /* Another thread won the race. Use their cache instead of ours */
886#ifdef __REACTOS__
887 list_remove(&new_sc->entry);
888#else
889 list_remove(&sc->entry);
890#endif
891 sc->refcount++;
893#ifdef __REACTOS__
894 free(new_sc);
895#else
896 free(*psc);
897#endif
898 *psc = sc;
899 return S_OK;
900 }
901 }
903#ifdef __REACTOS__
904 TRACE("<- %p\n", new_sc);
905#else
906 TRACE("<- %p\n", sc);
907#endif
908 return S_OK;
909}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
#define malloc
Definition: debug_ros.c:4
#define E_PENDING
Definition: dinput.h:172
#define lstrlenW
Definition: compat.h:750
#define MS_MAKE_TAG(ch0, ch1, ch2, ch3)
Definition: font.c:112
static struct list script_cache_list
Definition: usp10.c:614
static CRITICAL_SECTION cs_script_cache
Definition: usp10.c:606
static BOOL set_cache_font_properties(const HDC hdc, ScriptCache *sc)
Definition: usp10.c:684
uint32_t entry
Definition: isohybrid.c:63
HDC hdc
Definition: main.c:9
#define OBJ_FONT
Definition: objidl.idl:1019
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
OUTLINETEXTMETRICW * otm
struct list entry
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define NtGdiGetFontData(A, B, C, D, E)
Definition: wine-compat.h:4
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:428
#define GDI_ERROR
Definition: wingdi.h:1309
UINT WINAPI GetOutlineTextMetricsW(_In_ HDC hdc, _In_ UINT cjCopy, _Out_writes_bytes_opt_(cjCopy) LPOUTLINETEXTMETRICW potm)

Referenced by requires_fallback(), ScriptCacheGetHeight(), ScriptGetCMap(), ScriptGetFontFeatureTags(), ScriptGetFontLanguageTags(), ScriptGetFontProperties(), ScriptGetFontScriptTags(), ScriptGetGlyphABCWidth(), ScriptPlaceOpenType(), ScriptShapeOpenType(), and ScriptTextOut().

◆ is_indic()

static BOOL is_indic ( enum usp10_script  script)
inlinestatic

Definition at line 1277 of file usp10.c.

1278{
1280}

Referenced by _ItemizeInternal().

◆ mirror_char()

static WCHAR mirror_char ( WCHAR  ch)
static

Definition at line 911 of file usp10.c.

912{
913 extern const WCHAR wine_mirror_map[];
915 return mirror ? mirror : ch;
916}
const unsigned short wine_mirror_map[1428]
Definition: mirror.c:7
static unsigned short get_table_entry_16(const unsigned short *table, WCHAR ch)

Referenced by ScriptGetCMap(), and ScriptShapeOpenType().

◆ requires_fallback()

static BOOL requires_fallback ( HDC  hdc,
SCRIPT_CACHE *  psc,
SCRIPT_ANALYSIS *  psa,
const WCHAR *  pwcInChars,
int  cChars 
)
static

Definition at line 1903 of file usp10.c.

1905{
1906 /* FIXME: When to properly fallback is still a bit of a mystery */
1907 WORD *glyphs;
1908
1909 if (psa->fNoGlyphIndex)
1910 return FALSE;
1911
1912 if (init_script_cache(hdc, psc) != S_OK)
1913 return FALSE;
1914
1916 return TRUE;
1917
1918 if (!(glyphs = calloc(cChars, sizeof(*glyphs))))
1919 return FALSE;
1920 if (ScriptGetCMap(hdc, psc, pwcInChars, cChars, 0, glyphs) != S_OK)
1921 {
1922 free(glyphs);
1923 return TRUE;
1924 }
1925 free(glyphs);
1926
1927 return FALSE;
1928}
HRESULT WINAPI ScriptGetCMap(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcInChars, int cChars, DWORD dwFlags, WORD *pwOutGlyphs)
Definition: usp10.c:3563
static HRESULT init_script_cache(const HDC hdc, SCRIPT_CACHE *psc)
Definition: usp10.c:789
WORD fNoGlyphIndex
Definition: usp10.h:145
HRESULT SHAPE_CheckFontForRequiredFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa)
Definition: shape.c:3488

Referenced by ScriptStringAnalyse().

◆ script_is_numeric()

static BOOL script_is_numeric ( enum usp10_script  script)
static

Definition at line 1311 of file usp10.c.

1312{
1314}
DWORD fNumeric
Definition: usp10.h:108
SCRIPT_PROPERTIES props

Referenced by _ItemizeInternal().

◆ ScriptApplyDigitSubstitution()

HRESULT WINAPI ScriptApplyDigitSubstitution ( const SCRIPT_DIGITSUBSTITUTE *  sds,
SCRIPT_CONTROL *  sc,
SCRIPT_STATE *  ss 
)

Definition at line 1247 of file usp10.c.

1249{
1251
1252 TRACE("%p, %p, %p\n", sds, sc, ss);
1253
1254 if (!sc || !ss) return E_POINTER;
1255 if (!sds)
1256 {
1257 sds = &psds;
1259 return E_INVALIDARG;
1260 }
1261
1263 sc->fContextDigits = 0;
1264 ss->fDigitSubstitute = 0;
1265
1266 switch (sds->DigitSubstitute) {
1271 return S_OK;
1272 default:
1273 return E_INVALIDARG;
1274 }
1275}
HRESULT WINAPI ScriptRecordDigitSubstitution(LCID locale, SCRIPT_DIGITSUBSTITUTE *sds)
Definition: usp10.c:1181
#define ss
Definition: i386-dis.c:441
#define LOCALE_USER_DEFAULT
#define LANG_ENGLISH
Definition: nls.h:52
DWORD fContextDigits
Definition: usp10.h:94
DWORD uDefaultLanguage
Definition: usp10.h:93
#define SCRIPT_DIGITSUBSTITUTE_TRADITIONAL
Definition: usp10.h:67
#define SCRIPT_DIGITSUBSTITUTE_NONE
Definition: usp10.h:65
#define SCRIPT_DIGITSUBSTITUTE_CONTEXT
Definition: usp10.h:64
#define SCRIPT_DIGITSUBSTITUTE_NATIONAL
Definition: usp10.h:66
#define E_POINTER
Definition: winerror.h:3480

Referenced by enum_proc().

◆ ScriptApplyLogicalWidth()

HRESULT WINAPI ScriptApplyLogicalWidth ( const int *  dx,
int  num_chars,
int  num_glyphs,
const WORD *  log_clust,
const SCRIPT_VISATTR *  sva,
const int *  advance,
const SCRIPT_ANALYSIS *  sa,
ABC *  abc,
int *  justify 
)

Definition at line 4060 of file usp10.c.

4064{
4065 int i;
4066
4067 FIXME("(%p, %d, %d, %p, %p, %p, %p, %p, %p)\n",
4068 dx, num_chars, num_glyphs, log_clust, sva, advance, sa, abc, justify);
4069
4070 for (i = 0; i < num_chars; i++) justify[i] = advance[i];
4071 return S_OK;
4072}
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
GLint dx
Definition: linetemp.h:97

◆ ScriptBreak()

HRESULT WINAPI ScriptBreak ( const WCHAR *  chars,
int  count,
const SCRIPT_ANALYSIS *  sa,
SCRIPT_LOGATTR *  la 
)

Definition at line 3051 of file usp10.c.

3052{
3053 TRACE("(%s, %d, %p, %p)\n", debugstr_wn(chars, count), count, sa, la);
3054
3055 if (count < 0 || !la) return E_INVALIDARG;
3056 if (count == 0) return E_FAIL;
3057
3058 BREAK_line(chars, count, sa, la);
3059
3060 return S_OK;
3061}
void BREAK_line(const WCHAR *chars, int count, const SCRIPT_ANALYSIS *sa, SCRIPT_LOGATTR *la)
Definition: breaking.c:76
#define E_FAIL
Definition: ddrawi.h:102

Referenced by EDIT_WordBreakProc(), ScriptStringAnalyse(), test_ScriptBreak(), test_ScriptTextOut(), and word_break().

◆ ScriptCacheGetHeight()

HRESULT WINAPI ScriptCacheGetHeight ( HDC  hdc,
SCRIPT_CACHE *  psc,
LONG *  height 
)

Definition at line 3691 of file usp10.c.

3692{
3693 HRESULT hr;
3694
3695 TRACE("(%p, %p, %p)\n", hdc, psc, height);
3696
3697 if (!height) return E_INVALIDARG;
3698 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3699
3700 *height = get_cache_height(psc);
3701 return S_OK;
3702}
HRESULT hr
Definition: delayimp.cpp:582
static LONG get_cache_height(SCRIPT_CACHE *psc)
Definition: usp10.c:738
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546

Referenced by test_script_cache_reuse(), and test_ScriptCacheGetHeight().

◆ ScriptCPtoX()

HRESULT WINAPI ScriptCPtoX ( int  iCP,
BOOL  fTrailing,
int  cChars,
int  cGlyphs,
const WORD *  pwLogClust,
const SCRIPT_VISATTR *  psva,
const int *  piAdvance,
const SCRIPT_ANALYSIS *  psa,
int *  piX 
)

Definition at line 2654 of file usp10.c.

2663{
2664 int item;
2665 float iPosX;
2666 int iSpecial = -1;
2667 int iCluster = -1;
2668 int clust_size = 1;
2669 float special_size = 0.0;
2670 int iMaxPos = 0;
2671 int advance = 0;
2672 BOOL rtl = FALSE;
2673
2674 TRACE("(%d,%d,%d,%d,%p,%p,%p,%p,%p)\n",
2675 iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance,
2676 psa, piX);
2677
2678 if (psa->fRTL && ! psa->fLogicalOrder)
2679 rtl = TRUE;
2680
2681 if (fTrailing)
2682 iCP++;
2683
2684 if (rtl)
2685 {
2686 int max_clust = pwLogClust[0];
2687
2688 for (item=0; item < cGlyphs; item++)
2689 if (pwLogClust[item] > max_clust)
2690 {
2691 ERR("We do not handle non reversed clusters properly\n");
2692 break;
2693 }
2694
2695 iMaxPos = 0;
2696 for (item = max_clust; item >=0; item --)
2697 iMaxPos += piAdvance[item];
2698 }
2699
2700 iPosX = 0.0;
2701 for (item=0; item < iCP && item < cChars; item++)
2702 {
2703 if (iSpecial == -1 && (iCluster == -1 || iCluster+clust_size <= item))
2704 {
2705 int check;
2706 int clust = pwLogClust[item];
2707
2708 iCluster = -1;
2709 clust_size = get_cluster_size(pwLogClust, cChars, item, 1, &iCluster,
2710 &check);
2711
2712 advance = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, clust, 1);
2713
2714 if (check >= cChars && !iMaxPos)
2715 {
2716 int glyph;
2717 for (glyph = clust; glyph < cGlyphs; glyph++)
2718 special_size += get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, glyph, 1);
2719 iSpecial = item;
2720 special_size /= (cChars - item);
2721 iPosX += special_size;
2722 }
2723 else
2724 {
2726 {
2727 clust_size --;
2728 if (clust_size == 0)
2729 iPosX += advance;
2730 }
2731 else
2732 iPosX += advance / (float)clust_size;
2733 }
2734 }
2735 else if (iSpecial != -1)
2736 iPosX += special_size;
2737 else /* (iCluster != -1) */
2738 {
2739 int adv = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, pwLogClust[iCluster], 1);
2741 {
2742 clust_size --;
2743 if (clust_size == 0)
2744 iPosX += adv;
2745 }
2746 else
2747 iPosX += adv / (float)clust_size;
2748 }
2749 }
2750
2751 if (iMaxPos > 0)
2752 {
2753 iPosX = iMaxPos - iPosX;
2754 if (iPosX < 0)
2755 iPosX = 0;
2756 }
2757
2758 *piX = iPosX;
2759 TRACE("*piX=%d\n", *piX);
2760 return S_OK;
2761}
#define ERR(fmt,...)
Definition: precomp.h:57
static float(WINAPI *pD2D1Tan)(float angle)
static int get_cluster_size(const WORD *pwLogClust, int cChars, int item, int direction, int *iCluster, int *check_out)
Definition: usp10.c:2598
static int get_glyph_cluster_advance(const int *piAdvance, const SCRIPT_VISATTR *pva, const WORD *pwLogClust, int cGlyphs, int cChars, int glyph, int direction)
Definition: usp10.c:2622
static BOOL rtl
Definition: propsheet.c:36
DWORD fNeedsCaretInfo
Definition: usp10.h:111
WORD fLogicalOrder
Definition: usp10.h:144

Referenced by _test_item_ScriptXtoX(), ME_PointFromCharContext(), ScriptStringCPtoX(), ScriptStringXtoCP(), and test_ScriptTextOut().

◆ ScriptFreeCache()

HRESULT WINAPI ScriptFreeCache ( SCRIPT_CACHE *  psc)

Definition at line 1051 of file usp10.c.

1052{
1053 TRACE("%p\n", psc);
1054
1055 if (psc && *psc)
1056 {
1057 ScriptCache *sc = *psc;
1058 unsigned int i;
1059 INT n;
1060
1062 if (--sc->refcount > 0)
1063 {
1065 *psc = NULL;
1066 return S_OK;
1067 }
1068 list_remove(&sc->entry);
1070
1071 for (i = 0; i < GLYPH_MAX / GLYPH_BLOCK_SIZE; i++)
1072 {
1073 free(sc->widths[i]);
1074 }
1075 for (i = 0; i < NUM_PAGES; i++)
1076 {
1077 unsigned int j;
1078 if (sc->page[i])
1079 for (j = 0; j < GLYPH_MAX / GLYPH_BLOCK_SIZE; j++)
1080 free(sc->page[i]->glyphs[j]);
1081 free(sc->page[i]);
1082 }
1083 free(sc->GSUB_Table);
1084 free(sc->GDEF_Table);
1085 free(sc->CMAP_Table);
1086 free(sc->GPOS_Table);
1087 for (n = 0; n < sc->script_count; n++)
1088 {
1089 int j;
1090 for (j = 0; j < sc->scripts[n].language_count; j++)
1091 {
1092 int k;
1093 for (k = 0; k < sc->scripts[n].languages[j].feature_count; k++)
1096 }
1097 for (j = 0; j < sc->scripts[n].default_language.feature_count; j++)
1100 free(sc->scripts[n].languages);
1101 }
1102 free(sc->scripts);
1103 free(sc->otm);
1104 free(sc);
1105 *psc = NULL;
1106 }
1107 return S_OK;
1108}
static const uint32_t k[]
Definition: sha256.c:24
#define GLYPH_BLOCK_SIZE
#define GLYPH_MAX
GLdouble n
Definition: glext.h:7729
WORD * glyphs[GLYPH_MAX/GLYPH_BLOCK_SIZE]
LoadedFeature * features
LoadedLanguage * languages
SIZE_T language_count
LoadedLanguage default_language
void * GPOS_Table
ABC * widths[GLYPH_MAX/GLYPH_BLOCK_SIZE]
void * GDEF_Table
SIZE_T script_count
void * CMAP_Table
CacheGlyphPage * page[NUM_PAGES]
void * GSUB_Table
LoadedScript * scripts
#define NUM_PAGES

Referenced by _test_shape_ok(), BIDI_Reorder(), ME_DestroyStyle(), ME_SetDefaultCharFormat(), ScriptStringAnalyse(), ScriptStringFree(), test_script_cache_reuse(), test_ScriptCacheGetHeight(), test_ScriptGetCMap(), test_ScriptGetFontFunctions(), test_ScriptGetFontProperties(), test_ScriptGetGlyphABCWidth(), test_ScriptItemIzeShapePlace(), test_ScriptPlace(), test_ScriptShape(), test_ScriptShapeOpenType(), test_ScriptTextOut(), test_ScriptTextOut2(), and test_ScriptTextOut3().

◆ ScriptGetCMap()

HRESULT WINAPI ScriptGetCMap ( HDC  hdc,
SCRIPT_CACHE *  psc,
const WCHAR *  pwcInChars,
int  cChars,
DWORD  dwFlags,
WORD *  pwOutGlyphs 
)

Definition at line 3563 of file usp10.c.

3565{
3566 HRESULT hr;
3567 int i;
3568
3569 TRACE("(%p,%p,%s,%d,0x%lx,%p)\n", hdc, psc, debugstr_wn(pwcInChars, cChars),
3570 cChars, dwFlags, pwOutGlyphs);
3571
3572 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3573
3574 hr = S_OK;
3575
3576 for (i = 0; i < cChars; i++)
3577 {
3578 WCHAR inChar;
3579 if (dwFlags == SGCM_RTL)
3580 inChar = mirror_char(pwcInChars[i]);
3581 else
3582 inChar = pwcInChars[i];
3583 if (!(pwOutGlyphs[i] = get_cache_glyph(psc, inChar)))
3584 {
3585 WORD glyph;
3586 if (!hdc) return E_PENDING;
3588 return S_FALSE;
3589 if (glyph == 0xffff)
3590 {
3591 hr = S_FALSE;
3592 glyph = 0x0;
3593 }
3594 pwOutGlyphs[i] = set_cache_glyph(psc, inChar, glyph);
3595 }
3596 }
3597
3598 return hr;
3599}
static WORD get_cache_glyph(SCRIPT_CACHE *psc, DWORD c)
Definition: usp10.c:748
static WORD set_cache_glyph(SCRIPT_CACHE *psc, WCHAR c, WORD glyph)
Definition: usp10.c:759
static WCHAR mirror_char(WCHAR ch)
Definition: usp10.c:911
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define SGCM_RTL
Definition: usp10.h:61
#define NtGdiGetGlyphIndicesW(A, B, C, D, E)
Definition: wine-compat.h:3
#define S_FALSE
Definition: winerror.h:3451
#define GGI_MARK_NONEXISTING_GLYPHS
Definition: wingdi.h:1085

Referenced by requires_fallback(), ScriptPlaceOpenType(), and test_ScriptGetCMap().

◆ ScriptGetFontAlternateGlyphs()

HRESULT WINAPI ScriptGetFontAlternateGlyphs ( HDC  hdc,
SCRIPT_CACHE *  sc,
SCRIPT_ANALYSIS *  sa,
OPENTYPE_TAG  tag_script,
OPENTYPE_TAG  tag_langsys,
OPENTYPE_TAG  tag_feature,
WORD  id,
int  size,
WORD *  list,
int *  count 
)

Definition at line 4112 of file usp10.c.

4114{
4115 FIXME("(%p, %p, %p, %s, %s, %s, 0x%04x, %d, %p, %p)\n", hdc, sc, sa, debugstr_an((char*)&tag_script,4), debugstr_an((char*)&tag_langsys,4),
4116 debugstr_an((char*)&tag_feature,4), id, size, list, count);
4117
4118 if(count)
4119 *count = 0;
4120
4121 return E_NOTIMPL;
4122}
Definition: list.h:39
#define E_NOTIMPL
Definition: ddrawi.h:99
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55

◆ ScriptGetFontFeatureTags()

HRESULT WINAPI ScriptGetFontFeatureTags ( HDC  hdc,
SCRIPT_CACHE *  psc,
SCRIPT_ANALYSIS *  psa,
OPENTYPE_TAG  tagScript,
OPENTYPE_TAG  tagLangSys,
int  cMaxTags,
OPENTYPE_TAG *  pFeatureTags,
int *  pcTags 
)

Definition at line 4103 of file usp10.c.

4104{
4105 HRESULT hr;
4106 if (!pFeatureTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4107 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4108
4109 return SHAPE_GetFontFeatureTags(hdc, (ScriptCache *)*psc, psa, tagScript, tagLangSys, cMaxTags, pFeatureTags, pcTags);
4110}
HRESULT SHAPE_GetFontFeatureTags(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, OPENTYPE_TAG tagLangSys, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags)
Definition: shape.c:3557

Referenced by test_ScriptGetFontFunctions().

◆ ScriptGetFontLanguageTags()

HRESULT WINAPI ScriptGetFontLanguageTags ( HDC  hdc,
SCRIPT_CACHE *  psc,
SCRIPT_ANALYSIS *  psa,
OPENTYPE_TAG  tagScript,
int  cMaxTags,
OPENTYPE_TAG *  pLangSysTags,
int *  pcTags 
)

Definition at line 4094 of file usp10.c.

4095{
4096 HRESULT hr;
4097 if (!pLangSysTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4098 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4099
4100 return SHAPE_GetFontLanguageTags(hdc, (ScriptCache *)*psc, psa, tagScript, cMaxTags, pLangSysTags, pcTags);
4101}
HRESULT SHAPE_GetFontLanguageTags(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, int cMaxTags, OPENTYPE_TAG *pLangSysTags, int *pcTags)
Definition: shape.c:3529

Referenced by test_ScriptGetFontFunctions().

◆ ScriptGetFontProperties()

HRESULT WINAPI ScriptGetFontProperties ( HDC  hdc,
SCRIPT_CACHE *  psc,
SCRIPT_FONTPROPERTIES *  sfp 
)

Definition at line 1148 of file usp10.c.

1149{
1150 HRESULT hr;
1151
1152 TRACE("%p,%p,%p\n", hdc, psc, sfp);
1153
1154 if (!sfp) return E_INVALIDARG;
1155 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
1156
1157 if (sfp->cBytes != sizeof(SCRIPT_FONTPROPERTIES))
1158 return E_INVALIDARG;
1159
1160 get_cache_font_properties(sfp, *psc);
1161
1162 return S_OK;
1163}
static void get_cache_font_properties(SCRIPT_FONTPROPERTIES *sfp, ScriptCache *sc)
Definition: usp10.c:733

Referenced by test_ScriptGetFontProperties().

◆ ScriptGetFontScriptTags()

HRESULT WINAPI ScriptGetFontScriptTags ( HDC  hdc,
SCRIPT_CACHE *  psc,
SCRIPT_ANALYSIS *  psa,
int  cMaxTags,
OPENTYPE_TAG *  pScriptTags,
int *  pcTags 
)

Definition at line 4085 of file usp10.c.

4086{
4087 HRESULT hr;
4088 if (!pScriptTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4089 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4090
4091 return SHAPE_GetFontScriptTags(hdc, (ScriptCache *)*psc, psa, cMaxTags, pScriptTags, pcTags);
4092}
HRESULT SHAPE_GetFontScriptTags(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags)
Definition: shape.c:3511

Referenced by test_ScriptGetFontFunctions().

◆ ScriptGetGlyphABCWidth()

HRESULT WINAPI ScriptGetGlyphABCWidth ( HDC  hdc,
SCRIPT_CACHE *  psc,
WORD  glyph,
ABC *  abc 
)

Definition at line 3719 of file usp10.c.

3720{
3721 HRESULT hr;
3722
3723 TRACE("(%p, %p, 0x%04x, %p)\n", hdc, psc, glyph, abc);
3724
3725 if (!abc) return E_INVALIDARG;
3726 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3727
3728 if (!get_cache_glyph_widths(psc, glyph, abc))
3729 {
3730 if (!hdc) return E_PENDING;
3732 {
3733 if (!GetCharABCWidthsI(hdc, 0, 1, &glyph, abc)) return S_FALSE;
3734 }
3735 else
3736 {
3737 INT width;
3738 if (!GetCharWidthI(hdc, glyph, 1, NULL, &width)) return S_FALSE;
3739 abc->abcB = width;
3740 abc->abcA = abc->abcC = 0;
3741 }
3742 set_cache_glyph_widths(psc, glyph, abc);
3743 }
3744 return S_OK;
3745}
static BYTE get_cache_pitch_family(SCRIPT_CACHE *psc)
Definition: usp10.c:743
static BOOL set_cache_glyph_widths(SCRIPT_CACHE *psc, WORD glyph, ABC *abc)
Definition: usp10.c:780
static BOOL get_cache_glyph_widths(SCRIPT_CACHE *psc, WORD glyph, ABC *abc)
Definition: usp10.c:770
GLint GLint GLsizei width
Definition: gl.h:1546
int abcA
Definition: wingdi.h:1857
UINT abcB
Definition: wingdi.h:1858
int abcC
Definition: wingdi.h:1859
BOOL WINAPI GetCharWidthI(_In_ HDC hdc, _In_ UINT giFirst, _In_ UINT cgi, _In_reads_opt_(cgi) LPWORD pgi, _Out_writes_(cgi) LPINT piWidths)
#define TMPF_TRUETYPE
Definition: wingdi.h:1313
BOOL WINAPI GetCharABCWidthsI(_In_ HDC hdc, _In_ UINT giFirst, _In_ UINT cgi, _In_reads_opt_(cgi) LPWORD pgi, _Out_writes_(cgi) LPABC pabc)

Referenced by test_ScriptGetGlyphABCWidth().

◆ ScriptGetLogicalWidths()

HRESULT WINAPI ScriptGetLogicalWidths ( const SCRIPT_ANALYSIS *  sa,
int  nbchars,
int  nbglyphs,
const int *  advances,
const WORD *  log_clust,
const SCRIPT_VISATTR *  sva,
int *  widths 
)

Definition at line 4009 of file usp10.c.

4012{
4013 int i, next = 0, direction;
4014
4015 TRACE("(%p, %d, %d, %p, %p, %p, %p)\n",
4016 sa, nbchars, nbglyphs, advances, log_clust, sva, widths);
4017
4018 if (sa->fRTL && !sa->fLogicalOrder)
4019 direction = -1;
4020 else
4021 direction = 1;
4022
4023 for (i = 0; i < nbchars; i++)
4024 {
4025 int clust_size = get_cluster_size(log_clust, nbchars, i, direction, NULL, NULL);
4026 int advance = get_glyph_cluster_advance(advances, sva, log_clust, nbglyphs, nbchars, log_clust[i], direction);
4027 int j;
4028
4029 for (j = 0; j < clust_size; j++)
4030 {
4031 widths[next] = advance / clust_size;
4032 next++;
4033 if (j) i++;
4034 }
4035 }
4036
4037 return S_OK;
4038}
PSYMCRYPT_PARALLEL_HASH_OPERATION next

Referenced by test_ScriptGetLogicalWidths().

◆ ScriptGetProperties()

HRESULT WINAPI ScriptGetProperties ( const SCRIPT_PROPERTIES ***  props,
int *  num 
)

Definition at line 1126 of file usp10.c.

1127{
1128 TRACE("(%p,%p)\n", props, num);
1129
1130 if (!props && !num) return E_INVALIDARG;
1131
1132 if (num) *num = ARRAY_SIZE(script_props);
1133 if (props) *props = script_props;
1134
1135 return S_OK;
1136}
static const SCRIPT_PROPERTIES * script_props[]
Definition: usp10.c:561
GLuint GLuint num
Definition: glext.h:9618

Referenced by _test_shape_ok(), test_ScriptGetProperties(), test_ScriptItemIzeShapePlace(), and test_ScriptXtoX().

◆ ScriptIsComplex()

HRESULT WINAPI ScriptIsComplex ( const WCHAR *  chars,
int  len,
DWORD  flag 
)

Definition at line 3078 of file usp10.c.

3079{
3080 enum usp10_script script;
3081 unsigned int i, consumed;
3082
3083 TRACE("(%s,%d,0x%lx)\n", debugstr_wn(chars, len), len, flag);
3084
3085 if (!chars || len < 0)
3086 return E_INVALIDARG;
3087
3088 for (i = 0; i < len; i+=consumed)
3089 {
3090 if ((flag & SIC_ASCIIDIGIT) && chars[i] >= 0x30 && chars[i] <= 0x39)
3091 return S_OK;
3092
3093 script = get_char_script(chars,i,len, &consumed);
3094 if ((scriptInformation[script].props.fComplex && (flag & SIC_COMPLEX))||
3096 return S_OK;
3097 }
3098 return S_FALSE;
3099}
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
DWORD fComplex
Definition: usp10.h:109
#define SIC_COMPLEX
Definition: usp10.h:56
#define SIC_NEUTRAL
Definition: usp10.h:58
#define SIC_ASCIIDIGIT
Definition: usp10.h:57

Referenced by LPK_DrawUnderscore(), LpkExtTextOut(), LpkGetTextExtentExPoint(), and test_ScriptIsComplex().

◆ ScriptItemize()

HRESULT WINAPI ScriptItemize ( const WCHAR *  pwcInChars,
int  cInChars,
int  cMaxItems,
const SCRIPT_CONTROL *  psControl,
const SCRIPT_STATE *  psState,
SCRIPT_ITEM *  pItems,
int *  pcItems 
)

Definition at line 1822 of file usp10.c.

1825{
1826 return _ItemizeInternal(pwcInChars, cInChars, cMaxItems, psControl, psState, pItems, NULL, pcItems);
1827}
static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars, int cMaxItems, const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState, SCRIPT_ITEM *pItems, OPENTYPE_TAG *pScriptTags, int *pcItems)
Definition: usp10.c:1316

Referenced by BIDI_Reorder(), itemize_para(), ScriptStringAnalyse(), test_newlines(), test_ScriptBreak(), test_ScriptGetFontFunctions(), test_ScriptItemize(), test_ScriptItemize_surrogates(), test_ScriptItemIzeShapePlace(), test_ScriptPlace(), test_ScriptShape(), test_ScriptTextOut(), test_ScriptTextOut2(), test_ScriptTextOut3(), and test_ScriptXtoX().

◆ ScriptItemizeOpenType()

HRESULT WINAPI ScriptItemizeOpenType ( const WCHAR *  pwcInChars,
int  cInChars,
int  cMaxItems,
const SCRIPT_CONTROL *  psControl,
const SCRIPT_STATE *  psState,
SCRIPT_ITEM *  pItems,
OPENTYPE_TAG *  pScriptTags,
int *  pcItems 
)

Definition at line 1797 of file usp10.c.

1800{
1801 return _ItemizeInternal(pwcInChars, cInChars, cMaxItems, psControl, psState, pItems, pScriptTags, pcItems);
1802}

Referenced by _test_items_ok(), _test_shape_ok(), and test_ScriptShapeOpenType().

◆ ScriptJustify()

HRESULT WINAPI ScriptJustify ( const SCRIPT_VISATTR *  sva,
const int *  advance,
int  num_glyphs,
int  dx,
int  min_kashida,
int *  justify 
)

Definition at line 4074 of file usp10.c.

4076{
4077 int i;
4078
4079 FIXME("(%p, %p, %d, %d, %d, %p)\n", sva, advance, num_glyphs, dx, min_kashida, justify);
4080
4081 for (i = 0; i < num_glyphs; i++) justify[i] = advance[i];
4082 return S_OK;
4083}

◆ ScriptLayout()

HRESULT WINAPI ScriptLayout ( int  runs,
const BYTE *  level,
int *  vistolog,
int *  logtovis 
)

Definition at line 3763 of file usp10.c.

3764{
3765 int* indices;
3766 int ich;
3767
3768 TRACE("(%d, %p, %p, %p)\n", runs, level, vistolog, logtovis);
3769
3770 if (!level || (!vistolog && !logtovis))
3771 return E_INVALIDARG;
3772
3773 if (!(indices = calloc(runs, sizeof(*indices))))
3774 return E_OUTOFMEMORY;
3775
3776 if (vistolog)
3777 {
3778 for( ich = 0; ich < runs; ich++)
3779 indices[ich] = ich;
3780
3781 ich = 0;
3782 while (ich < runs)
3783 ich += BIDI_ReorderV2lLevel(0, indices+ich, level+ich, runs - ich, FALSE);
3784 memcpy(vistolog, indices, runs * sizeof(*vistolog));
3785 }
3786
3787 if (logtovis)
3788 {
3789 for( ich = 0; ich < runs; ich++)
3790 indices[ich] = ich;
3791
3792 ich = 0;
3793 while (ich < runs)
3794 ich += BIDI_ReorderL2vLevel(0, indices+ich, level+ich, runs - ich, FALSE);
3795 memcpy(logtovis, indices, runs * sizeof(*logtovis));
3796 }
3797 free(indices);
3798
3799 return S_OK;
3800}
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
int BIDI_ReorderL2vLevel(int level, int *pIndices, const BYTE *plevel, int cch, BOOL fReverse)
Definition: bidi.c:1214
int BIDI_ReorderV2lLevel(int level, int *pIndices, const BYTE *plevel, int cch, BOOL fReverse)
Definition: bidi.c:1187

Referenced by BIDI_Reorder(), BidiLines(), layout_row(), ScriptStringAnalyse(), and test_ScriptLayout().

◆ ScriptPlace()

HRESULT WINAPI ScriptPlace ( HDC  hdc,
SCRIPT_CACHE *  psc,
const WORD *  pwGlyphs,
int  cGlyphs,
const SCRIPT_VISATTR *  psva,
SCRIPT_ANALYSIS *  psa,
int *  piAdvance,
GOFFSET *  pGoffset,
ABC *  pABC 
)

Definition at line 3519 of file usp10.c.

3522{
3523 HRESULT hr;
3524 SCRIPT_GLYPHPROP *glyphProps;
3525 int i;
3526
3527 TRACE("(%p, %p, %p, %d, %p, %p, %p, %p, %p)\n", hdc, psc, pwGlyphs, cGlyphs, psva, psa,
3528 piAdvance, pGoffset, pABC);
3529
3530 if (!psva) return E_INVALIDARG;
3531 if (!pGoffset) return E_FAIL;
3532
3533 if (!(glyphProps = calloc(cGlyphs, sizeof(*glyphProps))))
3534 return E_OUTOFMEMORY;
3535
3536 for (i = 0; i < cGlyphs; i++)
3537 glyphProps[i].sva = psva[i];
3538
3539 hr = ScriptPlaceOpenType(hdc, psc, psa, scriptInformation[psa->eScript].scriptTag, 0, NULL, NULL, 0, NULL, NULL, NULL, 0, pwGlyphs, glyphProps, cGlyphs, piAdvance, pGoffset, pABC);
3540
3541 free(glyphProps);
3542
3543 return hr;
3544}
HRESULT WINAPI ScriptPlaceOpenType(HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, OPENTYPE_TAG tagLangSys, int *rcRangeChars, TEXTRANGE_PROPERTIES **rpRangeProperties, int cRanges, const WCHAR *pwcChars, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProps, int cChars, const WORD *pwGlyphs, const SCRIPT_GLYPHPROP *pGlyphProps, int cGlyphs, int *piAdvance, GOFFSET *pGoffset, ABC *pABC)
Definition: usp10.c:3396

Referenced by ScriptStringAnalyse(), shape_run(), test_ScriptItemIzeShapePlace(), test_ScriptPlace(), test_ScriptTextOut(), test_ScriptTextOut2(), and test_ScriptTextOut3().

◆ ScriptPlaceOpenType()

HRESULT WINAPI ScriptPlaceOpenType ( HDC  hdc,
SCRIPT_CACHE *  psc,
SCRIPT_ANALYSIS *  psa,
OPENTYPE_TAG  tagScript,
OPENTYPE_TAG  tagLangSys,
int *  rcRangeChars,
TEXTRANGE_PROPERTIES **  rpRangeProperties,
int  cRanges,
const WCHAR *  pwcChars,
WORD *  pwLogClust,
SCRIPT_CHARPROP *  pCharProps,
int  cChars,
const WORD *  pwGlyphs,
const SCRIPT_GLYPHPROP *  pGlyphProps,
int  cGlyphs,
int *  piAdvance,
GOFFSET *  pGoffset,
ABC *  pABC 
)

Definition at line 3396 of file usp10.c.

3405{
3406 HRESULT hr;
3407 int i;
3408 static int once = 0;
3409
3410 TRACE("(%p, %p, %p, %s, %s, %p, %p, %d, %s, %p, %p, %d, %p, %p, %d, %p %p %p)\n",
3411 hdc, psc, psa,
3412 debugstr_an((char*)&tagScript,4), debugstr_an((char*)&tagLangSys,4),
3413 rcRangeChars, rpRangeProperties, cRanges, debugstr_wn(pwcChars, cChars),
3414 pwLogClust, pCharProps, cChars, pwGlyphs, pGlyphProps, cGlyphs, piAdvance,
3415 pGoffset, pABC);
3416
3417 if (!pGlyphProps) return E_INVALIDARG;
3418 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3419 if (!pGoffset) return E_FAIL;
3420
3421 if (cRanges)
3422 if (!once++) FIXME("Ranges not supported yet\n");
3423
3424 ((ScriptCache *)*psc)->userScript = tagScript;
3425 ((ScriptCache *)*psc)->userLang = tagLangSys;
3426
3427 if (pABC) memset(pABC, 0, sizeof(ABC));
3428 for (i = 0; i < cGlyphs; i++)
3429 {
3430 WORD glyph;
3431 ABC abc;
3432
3433 /* FIXME: set to more reasonable values */
3434 pGoffset[i].du = pGoffset[i].dv = 0;
3435
3436 if (pGlyphProps[i].sva.fZeroWidth)
3437 {
3438 abc.abcA = abc.abcB = abc.abcC = 0;
3439 if (piAdvance) piAdvance[i] = 0;
3440 continue;
3441 }
3442
3443 if (psa->fNoGlyphIndex)
3444 {
3445 if (FAILED(hr = ScriptGetCMap(hdc, psc, &pwGlyphs[i], 1, 0, &glyph))) return hr;
3446 }
3447 else
3448 {
3449 hr = S_OK;
3450 glyph = pwGlyphs[i];
3451 }
3452
3453 if (hr == S_FALSE)
3454 {
3455 if (!hdc) return E_PENDING;
3457 {
3458 if (!GetCharABCWidthsW(hdc, pwGlyphs[i], pwGlyphs[i], &abc)) return S_FALSE;
3459 }
3460 else
3461 {
3462 INT width;
3463 if (!GetCharWidth32W(hdc, pwGlyphs[i], pwGlyphs[i], &width)) return S_FALSE;
3464 abc.abcB = width;
3465 abc.abcA = abc.abcC = 0;
3466 }
3467 }
3468 else if (!get_cache_glyph_widths(psc, glyph, &abc))
3469 {
3470 if (!hdc) return E_PENDING;
3472 {
3473 if (!GetCharABCWidthsI(hdc, glyph, 1, NULL, &abc)) return S_FALSE;
3474 }
3475 else
3476 {
3477 INT width;
3478 if (!GetCharWidthI(hdc, glyph, 1, NULL, &width)) return S_FALSE;
3479 abc.abcB = width;
3480 abc.abcA = abc.abcC = 0;
3481 }
3482 set_cache_glyph_widths(psc, glyph, &abc);
3483 }
3484 if (pABC)
3485 {
3486 pABC->abcA += abc.abcA;
3487 pABC->abcB += abc.abcB;
3488 pABC->abcC += abc.abcC;
3489 }
3490 if (piAdvance) piAdvance[i] = abc.abcA + abc.abcB + abc.abcC;
3491 }
3492
3493 SHAPE_ApplyOpenTypePositions(hdc, (ScriptCache *)*psc, psa, pwGlyphs, cGlyphs, piAdvance, pGoffset);
3494
3495 if (pABC) TRACE("Total for run: abcA=%d, abcB=%d, abcC=%d\n", pABC->abcA, pABC->abcB, pABC->abcC);
3496 return S_OK;
3497}
#define FAILED(hr)
Definition: intsafe.h:51
LONG dv
Definition: usp10.h:201
LONG du
Definition: usp10.h:200
void SHAPE_ApplyOpenTypePositions(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WORD *pwGlyphs, INT cGlyphs, int *piAdvance, GOFFSET *pGoffset)
Definition: shape.c:3463
BOOL WINAPI GetCharWidth32W(_In_ HDC hdc, _In_ UINT iFirst, _In_ UINT iLast, _Out_writes_(iLast+1 - iFirst) LPINT lpBuffer)
BOOL WINAPI GetCharABCWidthsW(_In_ HDC hdc, _In_ UINT wFirst, _In_ UINT wLast, _Out_writes_(wLast - wFirst+1) LPABC lpABC)

Referenced by ScriptPlace().

◆ ScriptRecordDigitSubstitution()

HRESULT WINAPI ScriptRecordDigitSubstitution ( LCID  locale,
SCRIPT_DIGITSUBSTITUTE *  sds 
)

Definition at line 1181 of file usp10.c.

1182{
1183 DWORD plgid, sub;
1184
1185 TRACE("0x%lx, %p\n", locale, sds);
1186
1187 /* This implementation appears to be correct for all languages, but it's
1188 * not clear if sds->DigitSubstitute is ever set to anything except
1189 * CONTEXT or NONE in reality */
1190
1191 if (!sds) return E_POINTER;
1192
1194
1196 return E_INVALIDARG;
1197
1199 sds->TraditionalDigitLanguage = plgid;
1200
1201 if (plgid == LANG_ARABIC || plgid == LANG_FARSI)
1202 sds->NationalDigitLanguage = plgid;
1203 else
1205
1206 if (!GetLocaleInfoW(locale, LOCALE_IDIGITSUBSTITUTION | LOCALE_RETURN_NUMBER,
1207 (WCHAR *)&sub, sizeof(sub) / sizeof(WCHAR)))
1208 return E_INVALIDARG;
1209
1210 switch (sub)
1211 {
1212 case 0:
1213 if (plgid == LANG_ARABIC || plgid == LANG_FARSI)
1215 else
1217 break;
1218 case 1:
1220 break;
1221 case 2:
1223 break;
1224 default:
1226 break;
1227 }
1228
1229 sds->dwReserved = 0;
1230 return S_OK;
1231}
Definition: _locale.h:75
BOOL WINAPI IsValidLocale(LCID lcid, DWORD flags)
Definition: locale.c:2925
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1675
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: locale.c:2879
#define LANG_FARSI
Definition: nls.h:55
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#define LANG_ARABIC
Definition: nls.h:29
#define PRIMARYLANGID(l)
Definition: nls.h:16
DWORD TraditionalDigitLanguage
Definition: usp10.h:156
#define LCID_INSTALLED
Definition: winnls.h:224

Referenced by enum_proc(), and ScriptApplyDigitSubstitution().

◆ ScriptShape()

HRESULT WINAPI ScriptShape ( HDC  hdc,
SCRIPT_CACHE *  psc,
const WCHAR *  pwcChars,
int  cChars,
int  cMaxGlyphs,
SCRIPT_ANALYSIS *  psa,
WORD *  pwOutGlyphs,
WORD *  pwLogClust,
SCRIPT_VISATTR *  psva,
int *  pcGlyphs 
)

Definition at line 3330 of file usp10.c.

3334{
3335 HRESULT hr;
3336 int i;
3337 SCRIPT_CHARPROP *charProps;
3338 SCRIPT_GLYPHPROP *glyphProps;
3339
3340 if (!psva || !pcGlyphs) return E_INVALIDARG;
3341 if (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
3342
3343 if (!(charProps = calloc(cChars, sizeof(*charProps))))
3344 return E_OUTOFMEMORY;
3345
3346 if (!(glyphProps = calloc(cMaxGlyphs, sizeof(*glyphProps))))
3347 {
3348 free(charProps);
3349 return E_OUTOFMEMORY;
3350 }
3351
3352 hr = ScriptShapeOpenType(hdc, psc, psa, scriptInformation[psa->eScript].scriptTag, 0, NULL, NULL, 0, pwcChars, cChars, cMaxGlyphs, pwLogClust, charProps, pwOutGlyphs, glyphProps, pcGlyphs);
3353
3354 if (SUCCEEDED(hr))
3355 {
3356 for (i = 0; i < *pcGlyphs; i++)
3357 psva[i] = glyphProps[i].sva;
3358 }
3359
3360 free(charProps);
3361 free(glyphProps);
3362
3363 return hr;
3364}
HRESULT WINAPI ScriptShapeOpenType(HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, OPENTYPE_TAG tagLangSys, int *rcRangeChars, TEXTRANGE_PROPERTIES **rpRangeProperties, int cRanges, const WCHAR *pwcChars, int cChars, int cMaxGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProps, WORD *pwOutGlyphs, SCRIPT_GLYPHPROP *pOutGlyphProps, int *pcGlyphs)
Definition: usp10.c:3128
#define SUCCEEDED(hr)
Definition: intsafe.h:50

Referenced by BIDI_Reorder(), ScriptStringAnalyse(), shape_run(), test_ScriptItemIzeShapePlace(), test_ScriptPlace(), test_ScriptShape(), test_ScriptTextOut(), test_ScriptTextOut2(), and test_ScriptTextOut3().

◆ ScriptShapeOpenType()

HRESULT WINAPI ScriptShapeOpenType ( HDC  hdc,
SCRIPT_CACHE *  psc,
SCRIPT_ANALYSIS *  psa,
OPENTYPE_TAG  tagScript,
OPENTYPE_TAG  tagLangSys,
int *  rcRangeChars,
TEXTRANGE_PROPERTIES **  rpRangeProperties,
int  cRanges,
const WCHAR *  pwcChars,
int  cChars,
int  cMaxGlyphs,
WORD *  pwLogClust,
SCRIPT_CHARPROP *  pCharProps,
WORD *  pwOutGlyphs,
SCRIPT_GLYPHPROP *  pOutGlyphProps,
int *  pcGlyphs 
)

Definition at line 3128 of file usp10.c.

3136{
3137 HRESULT hr;
3138 int i;
3139 unsigned int g;
3140 BOOL rtl;
3141 int cluster;
3142 static int once = 0;
3143
3144 TRACE("(%p, %p, %p, %s, %s, %p, %p, %d, %s, %d, %d, %p, %p, %p, %p, %p )\n",
3145 hdc, psc, psa,
3146 debugstr_an((char*)&tagScript,4), debugstr_an((char*)&tagLangSys,4),
3147 rcRangeChars, rpRangeProperties, cRanges, debugstr_wn(pwcChars, cChars),
3148 cChars, cMaxGlyphs, pwLogClust, pCharProps, pwOutGlyphs, pOutGlyphProps, pcGlyphs);
3149
3150 if (psa) TRACE("psa values: %d, %d, %d, %d, %d, %d, %d\n", psa->eScript, psa->fRTL, psa->fLayoutRTL,
3151 psa->fLinkBefore, psa->fLinkAfter, psa->fLogicalOrder, psa->fNoGlyphIndex);
3152
3153 if (!pOutGlyphProps || !pcGlyphs || !pCharProps) return E_INVALIDARG;
3154 if (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
3155
3156 if (cRanges)
3157 if(!once++) FIXME("Ranges not supported yet\n");
3158
3159 rtl = (psa && !psa->fLogicalOrder && psa->fRTL);
3160
3161 *pcGlyphs = cChars;
3162 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3163 if (!pwLogClust) return E_FAIL;
3164
3165 ((ScriptCache *)*psc)->userScript = tagScript;
3166 ((ScriptCache *)*psc)->userLang = tagLangSys;
3167
3168 /* Initialize a SCRIPT_VISATTR and LogClust for each char in this run */
3169 for (i = 0; i < cChars; i++)
3170 {
3171 int idx = i;
3172 if (rtl) idx = cChars - 1 - i;
3173 /* FIXME: set to better values */
3174 pOutGlyphProps[i].sva.uJustification = (pwcChars[idx] == ' ') ? SCRIPT_JUSTIFY_BLANK : SCRIPT_JUSTIFY_CHARACTER;
3175 pOutGlyphProps[i].sva.fClusterStart = 1;
3176 pOutGlyphProps[i].sva.fDiacritic = 0;
3177 pOutGlyphProps[i].sva.fZeroWidth = 0;
3178 pOutGlyphProps[i].sva.fReserved = 0;
3179 pOutGlyphProps[i].sva.fShapeReserved = 0;
3180
3181 /* FIXME: have the shaping engine set this */
3182 pCharProps[i].fCanGlyphAlone = 0;
3183
3184 pwLogClust[i] = idx;
3185 }
3186
3187 if (psa && !psa->fNoGlyphIndex && ((ScriptCache *)*psc)->sfnt)
3188 {
3189 WCHAR *rChars;
3190 if ((hr = SHAPE_CheckFontForRequiredFeatures(hdc, (ScriptCache *)*psc, psa)) != S_OK) return hr;
3191
3192 if (!(rChars = calloc(cChars, sizeof(*rChars))))
3193 return E_OUTOFMEMORY;
3194
3195 for (i = 0, g = 0, cluster = 0; i < cChars; i++)
3196 {
3197 int idx = i;
3198 DWORD chInput;
3199
3200 if (rtl) idx = cChars - 1 - i;
3201 if (!cluster)
3202 {
3203 chInput = decode_surrogate_pair(pwcChars, idx, cChars);
3204 if (!chInput)
3205 {
3206 if (psa->fRTL)
3207 chInput = mirror_char(pwcChars[idx]);
3208 else
3209 chInput = pwcChars[idx];
3210 rChars[i] = chInput;
3211 }
3212 else
3213 {
3214 rChars[i] = pwcChars[idx];
3215 rChars[i+1] = pwcChars[(rtl)?idx-1:idx+1];
3216 cluster = 1;
3217 }
3218 if (!(pwOutGlyphs[g] = get_cache_glyph(psc, chInput)))
3219 {
3220 WORD glyph;
3221 if (!hdc)
3222 {
3223 free(rChars);
3224 return E_PENDING;
3225 }
3226 if (OpenType_CMAP_GetGlyphIndex(hdc, (ScriptCache *)*psc, chInput, &glyph, 0) == GDI_ERROR)
3227 {
3228 free(rChars);
3229 return S_FALSE;
3230 }
3231 pwOutGlyphs[g] = set_cache_glyph(psc, chInput, glyph);
3232 }
3233 g++;
3234 }
3235 else
3236 {
3237 int k;
3238 cluster--;
3239 pwLogClust[idx] = (rtl)?pwLogClust[idx+1]:pwLogClust[idx-1];
3240 for (k = (rtl)?idx-1:idx+1; k >= 0 && k < cChars; (rtl)?k--:k++)
3241 pwLogClust[k]--;
3242 }
3243 }
3244 *pcGlyphs = g;
3245
3246 hr = SHAPE_ContextualShaping(hdc, (ScriptCache *)*psc, psa, rChars, cChars, pwOutGlyphs, pcGlyphs, cMaxGlyphs, pwLogClust);
3247 if (FAILED(hr))
3248 {
3249 free(rChars);
3250 return hr;
3251 }
3252 SHAPE_ApplyDefaultOpentypeFeatures(hdc, (ScriptCache *)*psc, psa, pwOutGlyphs, pcGlyphs, cMaxGlyphs, cChars, pwLogClust);
3253 SHAPE_CharGlyphProp(hdc, (ScriptCache *)*psc, psa, pwcChars, cChars, pwOutGlyphs, *pcGlyphs, pwLogClust, pCharProps, pOutGlyphProps);
3254
3255 for (i = 0; i < cChars; ++i)
3256 {
3257 /* Special case for tabs and joiners. As control characters, ZWNJ
3258 * and ZWJ would in principle get handled by the corresponding
3259 * shaping functions. However, since ZWNJ and ZWJ can get merged
3260 * into adjoining runs during itemisation, these don't generally
3261 * get classified as Script_Control. */
3262 if (pwcChars[i] == 0x0009 || pwcChars[i] == ZWSP || pwcChars[i] == ZWNJ || pwcChars[i] == ZWJ)
3263 {
3264 pwOutGlyphs[pwLogClust[i]] = ((ScriptCache *)*psc)->sfp.wgBlank;
3265 pOutGlyphProps[pwLogClust[i]].sva.fZeroWidth = 1;
3266 }
3267 }
3268 free(rChars);
3269 }
3270 else
3271 {
3272 TRACE("no glyph translation\n");
3273 for (i = 0; i < cChars; i++)
3274 {
3275 int idx = i;
3276 /* No mirroring done here */
3277 if (rtl) idx = cChars - 1 - i;
3278 pwOutGlyphs[i] = pwcChars[idx];
3279
3280 if (!psa)
3281 continue;
3282
3283 /* overwrite some basic control glyphs to blank */
3284 if (psa->fNoGlyphIndex)
3285 {
3286 if (pwcChars[idx] == ZWSP || pwcChars[idx] == ZWNJ || pwcChars[idx] == ZWJ)
3287 {
3288 pwOutGlyphs[i] = 0x20;
3289 pOutGlyphProps[i].sva.fZeroWidth = 1;
3290 }
3291 }
3292 else if (psa->eScript == Script_Control || pwcChars[idx] == ZWSP
3293 || pwcChars[idx] == ZWNJ || pwcChars[idx] == ZWJ)
3294 {
3295 if (pwcChars[idx] == 0x0009 || pwcChars[idx] == 0x000A ||
3296 pwcChars[idx] == 0x000D || pwcChars[idx] >= 0x001C)
3297 {
3298 pwOutGlyphs[i] = ((ScriptCache *)*psc)->sfp.wgBlank;
3299 pOutGlyphProps[i].sva.fZeroWidth = 1;
3300 }
3301 }
3302 }
3303 }
3304
3305 return S_OK;
3306}
@ SCRIPT_JUSTIFY_BLANK
@ SCRIPT_JUSTIFY_CHARACTER
GLboolean GLboolean g
Definition: glext.h:6204
WORD fCanGlyphAlone
Definition: usp10.h:221
SCRIPT_VISATTR sva
Definition: usp10.h:215
WORD uJustification
Definition: usp10.h:178
WORD fClusterStart
Definition: usp10.h:179
WORD fShapeReserved
Definition: usp10.h:183
SFNT_Service sfnt
Definition: ttdriver.c:208
DWORD OpenType_CMAP_GetGlyphIndex(HDC hdc, ScriptCache *psc, DWORD utf32c, WORD *glyph_index, DWORD flags)
Definition: opentype.c:677
void SHAPE_ApplyDefaultOpentypeFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WORD *pwOutGlyphs, INT *pcGlyphs, INT cMaxGlyphs, INT cChars, WORD *pwLogClust)
Definition: shape.c:3455
void SHAPE_CharGlyphProp(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR *pwcChars, const INT cChars, const WORD *pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProp, SCRIPT_GLYPHPROP *pGlyphProp)
Definition: shape.c:3411
HRESULT SHAPE_ContextualShaping(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR *pwcChars, INT cChars, WORD *pwOutGlyphs, INT *pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust)
Definition: shape.c:3421

Referenced by _test_shape_ok(), ScriptShape(), and test_ScriptShapeOpenType().

◆ ScriptString_pcOutChars()

const int *WINAPI ScriptString_pcOutChars ( SCRIPT_STRING_ANALYSIS  ssa)

Definition at line 3949 of file usp10.c.

3950{
3951 StringAnalysis *analysis = ssa;
3952
3953 TRACE("(%p)\n", ssa);
3954
3955 if (!analysis) return NULL;
3956 return &analysis->clip_len;
3957}
int clip_len
Definition: usp10.c:639

Referenced by EDIT_BuildLineDefs_ML(), and test_ScriptString().

◆ ScriptString_pLogAttr()

const SCRIPT_LOGATTR *WINAPI ScriptString_pLogAttr ( SCRIPT_STRING_ANALYSIS  ssa)

Definition at line 3926 of file usp10.c.

3927{
3928 StringAnalysis *analysis = ssa;
3929
3930 TRACE("(%p)\n", ssa);
3931
3932 if (!analysis) return NULL;
3933 if (!(analysis->ssa_flags & SSA_BREAK)) return NULL;
3934 return analysis->logattrs;
3935}
DWORD ssa_flags
Definition: usp10.c:637
SCRIPT_LOGATTR * logattrs
Definition: usp10.c:645
#define SSA_BREAK
Definition: usp10.h:39

◆ ScriptString_pSize()

const SIZE *WINAPI ScriptString_pSize ( SCRIPT_STRING_ANALYSIS  ssa)

Definition at line 3887 of file usp10.c.

3888{
3889 int i, j;
3890 StringAnalysis *analysis = ssa;
3891
3892 TRACE("(%p)\n", ssa);
3893
3894 if (!analysis) return NULL;
3895 if (!(analysis->ssa_flags & SSA_GLYPHS)) return NULL;
3896
3897 if (!(analysis->flags & SCRIPT_STRING_ANALYSIS_FLAGS_SIZE))
3898 {
3899 analysis->sz.cy = analysis->glyphs[0].sc->tm.tmHeight;
3900
3901 analysis->sz.cx = 0;
3902 for (i = 0; i < analysis->numItems; i++)
3903 {
3904 if (analysis->glyphs[i].sc->tm.tmHeight > analysis->sz.cy)
3905 analysis->sz.cy = analysis->glyphs[i].sc->tm.tmHeight;
3906 for (j = 0; j < analysis->glyphs[i].numGlyphs; j++)
3907 analysis->sz.cx += analysis->glyphs[i].piAdvance[j];
3908 }
3910 }
3911 return &analysis->sz;
3912}
StringGlyphs * glyphs
Definition: usp10.c:644
DWORD flags
Definition: usp10.c:638
int numItems
Definition: usp10.c:643
ScriptCache * sc
Definition: usp10.c:617
int * piAdvance
Definition: usp10.c:621
int numGlyphs
Definition: usp10.c:618
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
LONG tmHeight
Definition: wingdi.h:2829
#define SSA_GLYPHS
Definition: usp10.h:40

Referenced by EDIT_BuildLineDefs_ML(), EDIT_CalcLineWidth_SL(), EDIT_CharFromPos(), EDIT_EM_PosFromChar(), and test_ScriptString_pSize().

◆ ScriptStringAnalyse()

HRESULT WINAPI ScriptStringAnalyse ( HDC  hdc,
const void *  pString,
int  cString,
int  cGlyphs,
int  iCharset,
DWORD  dwFlags,
int  iReqWidth,
SCRIPT_CONTROL *  psControl,
SCRIPT_STATE *  psState,
const int *  piDx,
SCRIPT_TABDEF *  pTabdef,
const BYTE *  pbInClass,
SCRIPT_STRING_ANALYSIS *  pssa 
)

Definition at line 1953 of file usp10.c.

1959{
1961 StringAnalysis *analysis = NULL;
1962 SCRIPT_CONTROL sControl;
1963 SCRIPT_STATE sState;
1964 int i, num_items = cString + 1;
1965 BYTE *BidiLevel = NULL;
1966 WCHAR *iString = NULL;
1968
1969 TRACE("(%p,%p,%d,%d,%d,0x%lx,%d,%p,%p,%p,%p,%p,%p)\n",
1970 hdc, pString, cString, cGlyphs, iCharset, dwFlags, iReqWidth,
1971 psControl, psState, piDx, pTabdef, pbInClass, pssa);
1972
1973 if (iCharset != -1)
1974 {
1975 FIXME("Only Unicode strings are supported\n");
1976 return E_INVALIDARG;
1977 }
1978 if (cString < 1 || !pString) return E_INVALIDARG;
1979 if ((dwFlags & SSA_GLYPHS) && !hdc) return E_PENDING;
1980
1981 if (!(analysis = calloc(1, sizeof(*analysis))))
1982 return E_OUTOFMEMORY;
1983 if (!(analysis->pItem = calloc(num_items, sizeof(*analysis->pItem))))
1984 goto error;
1985
1986 /* FIXME: handle clipping */
1987 analysis->clip_len = cString;
1988 analysis->hdc = hdc;
1989 analysis->ssa_flags = dwFlags;
1990
1991 if (psState)
1992 sState = *psState;
1993 else
1994 memset(&sState, 0, sizeof(SCRIPT_STATE));
1995
1996 if (psControl)
1997 sControl = *psControl;
1998 else
1999 memset(&sControl, 0, sizeof(SCRIPT_CONTROL));
2000
2001 if (dwFlags & SSA_PASSWORD)
2002 {
2003 if (!(iString = calloc(cString, sizeof(*iString))))
2004 {
2005 hr = E_OUTOFMEMORY;
2006 goto error;
2007 }
2008 for (i = 0; i < cString; i++)
2009 iString[i] = *((const WCHAR *)pString);
2010 pString = iString;
2011 }
2012
2013 hr = ScriptItemize(pString, cString, num_items, &sControl, &sState, analysis->pItem,
2014 &analysis->numItems);
2015 if (FAILED(hr))
2016 goto error;
2017
2018 /* Having as many items as codepoints is the worst case scenario, try to reclaim some memory. */
2019 if ((items = realloc(analysis->pItem, (analysis->numItems + 1) * sizeof(*analysis->pItem))))
2020 analysis->pItem = items;
2021
2022 /* set back to out of memory for default goto error behaviour */
2023 hr = E_OUTOFMEMORY;
2024
2025 if (dwFlags & SSA_BREAK)
2026 {
2027 if (!(analysis->logattrs = calloc(cString, sizeof(*analysis->logattrs))))
2028 goto error;
2029
2030 for (i = 0; i < analysis->numItems; ++i)
2031 ScriptBreak(&((const WCHAR *)pString)[analysis->pItem[i].iCharPos],
2032 analysis->pItem[i + 1].iCharPos - analysis->pItem[i].iCharPos,
2033 &analysis->pItem[i].a, &analysis->logattrs[analysis->pItem[i].iCharPos]);
2034 }
2035
2036 if (!(analysis->logical2visual = calloc(analysis->numItems, sizeof(*analysis->logical2visual))))
2037 goto error;
2038 if (!(BidiLevel = calloc(analysis->numItems, sizeof(*BidiLevel))))
2039 goto error;
2040
2041 if (dwFlags & SSA_GLYPHS)
2042 {
2043 int tab_x = 0;
2044
2045 if (!(analysis->glyphs = calloc(analysis->numItems, sizeof(*analysis->glyphs))))
2046 goto error;
2047
2048 for (i = 0; i < analysis->numItems; i++)
2049 {
2050 SCRIPT_CACHE *sc = (SCRIPT_CACHE*)&analysis->glyphs[i].sc;
2051 int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
2052 int multiplier = 2;
2053 int numGlyphs;
2054 WORD *glyphs = NULL;
2055 WORD *pwLogClust = calloc(cChar, sizeof(*pwLogClust));
2056 int *piAdvance = NULL;
2057 SCRIPT_VISATTR *psva = NULL;
2058 GOFFSET *pGoffset = NULL;
2059 int numGlyphsReturned;
2060 HFONT originalFont = 0x0;
2061
2062 /* FIXME: non unicode strings */
2063 const WCHAR* pStr = (const WCHAR*)pString;
2064 analysis->glyphs[i].fallbackFont = NULL;
2065
2066 if (!pwLogClust)
2067 {
2068 hr = E_OUTOFMEMORY;
2069 goto error;
2070 }
2071
2072 if ((dwFlags & SSA_FALLBACK) && requires_fallback(hdc, sc, &analysis->pItem[i].a, &pStr[analysis->pItem[i].iCharPos], cChar))
2073 {
2074 LOGFONTW lf;
2075 GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), & lf);
2077 lf.lfFaceName[0] = 0;
2078 find_fallback_font(analysis->pItem[i].a.eScript, lf.lfFaceName);
2079 if (lf.lfFaceName[0])
2080 {
2081 analysis->glyphs[i].fallbackFont = CreateFontIndirectW(&lf);
2082 if (analysis->glyphs[i].fallbackFont)
2083 {
2084 ScriptFreeCache(sc);
2085 originalFont = SelectObject(hdc, analysis->glyphs[i].fallbackFont);
2086 }
2087 }
2088 }
2089
2090 /* FIXME: When we properly shape Hangul remove this check */
2091 if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && analysis->pItem[i].a.eScript == Script_Hangul)
2092 analysis->pItem[i].a.fNoGlyphIndex = TRUE;
2093
2094 if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && !scriptInformation[analysis->pItem[i].a.eScript].props.fComplex && !analysis->pItem[i].a.fRTL)
2095 analysis->pItem[i].a.fNoGlyphIndex = TRUE;
2096
2097 while (TRUE)
2098 {
2099 if (multiplier > 8)
2100 {
2101 hr = E_OUTOFMEMORY;
2102 break;
2103 }
2104
2105 free(glyphs);
2106 free(piAdvance);
2107 free(psva);
2108 free(pGoffset);
2109
2110 numGlyphs = multiplier * cChar + 16;
2111 glyphs = calloc(numGlyphs, sizeof(*glyphs));
2112 piAdvance = calloc(numGlyphs, sizeof(*piAdvance));
2113 psva = calloc(numGlyphs, sizeof(*psva));
2114 pGoffset = calloc(numGlyphs, sizeof(*pGoffset));
2115
2116 if (!glyphs || !piAdvance || !psva || !pGoffset)
2117 {
2118 hr = E_OUTOFMEMORY;
2119 break;
2120 }
2121
2122 hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos], cChar, numGlyphs,
2123 &analysis->pItem[i].a, glyphs, pwLogClust, psva, &numGlyphsReturned);
2124 if (hr == E_OUTOFMEMORY)
2125 {
2126 multiplier *= 2;
2127 continue;
2128 }
2129
2130 hr = ScriptPlace(hdc, sc, glyphs, numGlyphsReturned, psva, &analysis->pItem[i].a,
2131 piAdvance, pGoffset, &analysis->glyphs[i].abc);
2132 break;
2133 }
2134
2135 if (originalFont)
2136 SelectObject(hdc,originalFont);
2137
2138 if (FAILED(hr))
2139 {
2140 free(glyphs);
2141 free(pwLogClust);
2142 free(piAdvance);
2143 free(psva);
2144 free(pGoffset);
2145 goto error;
2146 }
2147
2148 if (dwFlags & SSA_TAB)
2149 {
2150 int tabi = 0;
2151 for (tabi = 0; tabi < cChar; tabi++)
2152 {
2153 if (pStr[analysis->pItem[i].iCharPos+tabi] == 0x0009)
2154 piAdvance[tabi] = getGivenTabWidth(analysis->glyphs[i].sc, pTabdef, analysis->pItem[i].iCharPos+tabi, tab_x);
2155 tab_x+=piAdvance[tabi];
2156 }
2157 }
2158
2159 analysis->glyphs[i].numGlyphs = numGlyphsReturned;
2160 analysis->glyphs[i].glyphs = glyphs;
2161 analysis->glyphs[i].pwLogClust = pwLogClust;
2162 analysis->glyphs[i].piAdvance = piAdvance;
2163 analysis->glyphs[i].psva = psva;
2164 analysis->glyphs[i].pGoffset = pGoffset;
2165 analysis->glyphs[i].iMaxPosX= -1;
2166
2167 BidiLevel[i] = analysis->pItem[i].a.s.uBidiLevel;
2168 }
2169 }
2170 else
2171 {
2172 for (i = 0; i < analysis->numItems; i++)
2173 BidiLevel[i] = analysis->pItem[i].a.s.uBidiLevel;
2174 }
2175
2176 ScriptLayout(analysis->numItems, BidiLevel, NULL, analysis->logical2visual);
2177 free(BidiLevel);
2178
2179 *pssa = analysis;
2180 free(iString);
2181 return S_OK;
2182
2183error:
2184 free(iString);
2185 free(BidiLevel);
2186 free(analysis->glyphs);
2187 free(analysis->logattrs);
2188 free(analysis->pItem);
2189 free(analysis->logical2visual);
2190 free(analysis);
2191 return hr;
2192}
#define realloc
Definition: debug_ros.c:6
HRESULT WINAPI ScriptPlace(HDC hdc, SCRIPT_CACHE *psc, const WORD *pwGlyphs, int cGlyphs, const SCRIPT_VISATTR *psva, SCRIPT_ANALYSIS *psa, int *piAdvance, GOFFSET *pGoffset, ABC *pABC)
Definition: usp10.c:3519
static int getGivenTabWidth(ScriptCache *psc, SCRIPT_TABDEF *pTabdef, int charPos, int current_x)
Definition: usp10.c:1829
HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc)
Definition: usp10.c:1051
HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItems, const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState, SCRIPT_ITEM *pItems, int *pcItems)
Definition: usp10.c:1822
HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, int cChars, int cMaxGlyphs, SCRIPT_ANALYSIS *psa, WORD *pwOutGlyphs, WORD *pwLogClust, SCRIPT_VISATTR *psva, int *pcGlyphs)
Definition: usp10.c:3330
HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *logtovis)
Definition: usp10.c:3763
static BOOL requires_fallback(HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, const WCHAR *pwcInChars, int cChars)
Definition: usp10.c:1903
static void find_fallback_font(enum usp10_script scriptid, WCHAR *FaceName)
Definition: usp10.c:1930
HRESULT WINAPI ScriptBreak(const WCHAR *chars, int count, const SCRIPT_ANALYSIS *sa, SCRIPT_LOGATTR *la)
Definition: usp10.c:3051
FxString * pString
GLenum const GLvoid GLbitfield GLsizei numGlyphs
Definition: glext.h:11715
#define error(str)
Definition: mkdosfs.c:1605
static TCHAR * items[]
Definition: page1.c:45
@ Script_Hangul
Definition: scripts.h:40
BYTE lfCharSet
Definition: dimm.idl:67
DWORD bCharSet
Definition: usp10.h:112
int * logical2visual
Definition: usp10.c:647
SCRIPT_ITEM * pItem
Definition: usp10.c:642
SCRIPT_VISATTR * psva
Definition: usp10.c:622
int iMaxPosX
Definition: usp10.c:625
WORD * pwLogClust
Definition: usp10.c:620
HFONT fallbackFont
Definition: usp10.c:626
WORD * glyphs
Definition: usp10.c:619
ABC abc
Definition: usp10.c:624
GOFFSET * pGoffset
Definition: usp10.c:623
#define SSA_TAB
Definition: usp10.h:34
#define SSA_FALLBACK
Definition: usp10.h:38
#define SSA_LINK
Definition: usp10.h:45
#define SSA_PASSWORD
Definition: usp10.h:33
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)

Referenced by EDIT_UpdateUniscribeData(), EDIT_UpdateUniscribeData_linedef(), LPK_DrawUnderscore(), LpkGetCharacterPlacement(), LpkGetTextExtentExPoint(), test_ScriptString(), test_ScriptString_pSize(), and test_ScriptStringXtoCP_CPtoX().

◆ ScriptStringCPtoX()

HRESULT WINAPI ScriptStringCPtoX ( SCRIPT_STRING_ANALYSIS  ssa,
int  icp,
BOOL  fTrailing,
int *  pX 
)

Definition at line 2416 of file usp10.c.

2417{
2418 int item;
2419 int runningX = 0;
2420 StringAnalysis* analysis = ssa;
2421
2422 TRACE("(%p), %d, %d, (%p)\n", ssa, icp, fTrailing, pX);
2423
2424 if (!ssa || !pX) return S_FALSE;
2425 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
2426
2427 /* icp out of range */
2428 if(icp < 0)
2429 {
2431 return E_INVALIDARG;
2432 }
2433
2434 for(item=0; item<analysis->numItems; item++)
2435 {
2436 int CP, i;
2437 int offset;
2438
2439 i = analysis->logical2visual[item];
2440 CP = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
2441 /* initialize max extents for uninitialized runs */
2442 if (analysis->glyphs[i].iMaxPosX == -1)
2443 {
2444 if (analysis->pItem[i].a.fRTL)
2445 ScriptCPtoX(0, FALSE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2446 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2447 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2448 else
2449 ScriptCPtoX(CP, TRUE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2450 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2451 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2452 }
2453
2454 if (icp >= analysis->pItem[i+1].iCharPos || icp < analysis->pItem[i].iCharPos)
2455 {
2456 runningX += analysis->glyphs[i].iMaxPosX;
2457 continue;
2458 }
2459
2460 icp -= analysis->pItem[i].iCharPos;
2461 ScriptCPtoX(icp, fTrailing, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2462 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2463 &analysis->pItem[i].a, &offset);
2464 runningX += offset;
2465
2466 *pX = runningX;
2467 return S_OK;
2468 }
2469
2470 /* icp out of range */
2472 return E_INVALIDARG;
2473}
HRESULT WINAPI ScriptCPtoX(int iCP, BOOL fTrailing, int cChars, int cGlyphs, const WORD *pwLogClust, const SCRIPT_VISATTR *psva, const int *piAdvance, const SCRIPT_ANALYSIS *psa, int *piX)
Definition: usp10.c:2654
#define CP
Definition: debug.h:64
GLintptr offset
Definition: glext.h:5920

Referenced by EDIT_CharFromPos(), EDIT_EM_PosFromChar(), EDIT_GetLineRect(), LPK_DrawUnderscore(), LpkGetCharacterPlacement(), SS_ItemOut(), and test_ScriptStringXtoCP_CPtoX().

◆ ScriptStringFree()

HRESULT WINAPI ScriptStringFree ( SCRIPT_STRING_ANALYSIS *  pssa)

Definition at line 2561 of file usp10.c.

2562{
2563 StringAnalysis* analysis;
2564 BOOL invalid;
2565 int i;
2566
2567 TRACE("(%p)\n", pssa);
2568
2569 if (!pssa || !(analysis = *pssa)) return E_INVALIDARG;
2570
2572
2573 if (analysis->glyphs)
2574 {
2575 for (i = 0; i < analysis->numItems; i++)
2576 {
2577 free(analysis->glyphs[i].glyphs);
2578 free(analysis->glyphs[i].pwLogClust);
2579 free(analysis->glyphs[i].piAdvance);
2580 free(analysis->glyphs[i].psva);
2581 free(analysis->glyphs[i].pGoffset);
2582 if (analysis->glyphs[i].fallbackFont)
2583 DeleteObject(analysis->glyphs[i].fallbackFont);
2584 ScriptFreeCache((SCRIPT_CACHE *)&analysis->glyphs[i].sc);
2585 }
2586 free(analysis->glyphs);
2587 }
2588
2589 free(analysis->pItem);
2590 free(analysis->logattrs);
2591 free(analysis->logical2visual);
2592 free(analysis);
2593
2594 if (invalid) return E_INVALIDARG;
2595 return S_OK;
2596}
pKey DeleteObject()

Referenced by EDIT_InvalidateUniscribeData(), EDIT_InvalidateUniscribeData_linedef(), LPK_DrawUnderscore(), LpkGetCharacterPlacement(), LpkGetTextExtentExPoint(), test_ScriptString(), test_ScriptString_pSize(), and test_ScriptStringXtoCP_CPtoX().

◆ ScriptStringGetLogicalWidths()

HRESULT WINAPI ScriptStringGetLogicalWidths ( SCRIPT_STRING_ANALYSIS  ssa,
int *  piDx 
)

Definition at line 3815 of file usp10.c.

3816{
3817 int i, j, next = 0;
3818 StringAnalysis *analysis = ssa;
3819
3820 TRACE("%p, %p\n", ssa, piDx);
3821
3822 if (!analysis) return S_FALSE;
3823 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
3824
3825 for (i = 0; i < analysis->numItems; i++)
3826 {
3827 int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
3828 int direction = 1;
3829
3830 if (analysis->pItem[i].a.fRTL && ! analysis->pItem[i].a.fLogicalOrder)
3831 direction = -1;
3832
3833 for (j = 0; j < cChar; j++)
3834 {
3835 int k;
3836 int glyph = analysis->glyphs[i].pwLogClust[j];
3837 int clust_size = get_cluster_size(analysis->glyphs[i].pwLogClust,
3838 cChar, j, direction, NULL, NULL);
3839 int advance = get_glyph_cluster_advance(analysis->glyphs[i].piAdvance, analysis->glyphs[i].psva, analysis->glyphs[i].pwLogClust, analysis->glyphs[i].numGlyphs, cChar, glyph, direction);
3840
3841 for (k = 0; k < clust_size; k++)
3842 {
3843 piDx[next] = advance / clust_size;
3844 next++;
3845 if (k) j++;
3846 }
3847 }
3848 }
3849 return S_OK;
3850}

Referenced by EDIT_BuildLineDefs_ML(), and LpkGetTextExtentExPoint().

◆ ScriptStringGetOrder()

HRESULT WINAPI ScriptStringGetOrder ( SCRIPT_STRING_ANALYSIS  ssa,
UINT *  order 
)

Definition at line 3972 of file usp10.c.

3973{
3974 int i, j;
3975 unsigned int k;
3976 StringAnalysis *analysis = ssa;
3977
3978 TRACE("(%p)\n", ssa);
3979
3980 if (!analysis) return S_FALSE;
3981 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
3982
3983 /* FIXME: handle RTL scripts */
3984 for (i = 0, k = 0; i < analysis->numItems; i++)
3985 for (j = 0; j < analysis->glyphs[i].numGlyphs; j++, k++)
3986 order[k] = k;
3987
3988 return S_OK;
3989}
GLuint GLdouble GLdouble GLint GLint order
Definition: glext.h:11194

Referenced by test_ScriptString().

◆ ScriptStringOut()

HRESULT WINAPI ScriptStringOut ( SCRIPT_STRING_ANALYSIS  ssa,
int  iX,
int  iY,
UINT  uOptions,
const RECT *  prc,
int  iMinSel,
int  iMaxSel,
BOOL  fDisabled 
)

Definition at line 2371 of file usp10.c.

2379{
2380 StringAnalysis *analysis;
2381 int item;
2382 HRESULT hr;
2383
2384 TRACE("(%p,%d,%d,0x%08x,%s,%d,%d,%d)\n",
2385 ssa, iX, iY, uOptions, wine_dbgstr_rect(prc), iMinSel, iMaxSel, fDisabled);
2386
2387 if (!(analysis = ssa)) return E_INVALIDARG;
2388 if (!(analysis->ssa_flags & SSA_GLYPHS)) return E_INVALIDARG;
2389
2390 for (item = 0; item < analysis->numItems; item++)
2391 {
2392 hr = SS_ItemOut( ssa, iX, iY, analysis->logical2visual[item], -1, -1, uOptions, prc, FALSE, fDisabled);
2393 if (FAILED(hr))
2394 return hr;
2395 }
2396
2397 if (iMinSel < iMaxSel && (iMinSel > 0 || iMaxSel > 0))
2398 {
2399 if (iMaxSel > 0 && iMinSel < 0)
2400 iMinSel = 0;
2401 for (item = 0; item < analysis->numItems; item++)
2402 {
2403 hr = SS_ItemOut( ssa, iX, iY, analysis->logical2visual[item], iMinSel, iMaxSel, uOptions, prc, TRUE, fDisabled);
2404 if (FAILED(hr))
2405 return hr;
2406 }
2407 }
2408
2409 return S_OK;
2410}
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
static HRESULT SS_ItemOut(SCRIPT_STRING_ANALYSIS ssa, int iX, int iY, int iItem, int cStart, int cEnd, UINT uOptions, const RECT *prc, BOOL fSelected, BOOL fDisabled)
Definition: usp10.c:2204
_Out_ LPRECT prc
Definition: ntgdi.h:1678

Referenced by EDIT_PaintLine(), and test_ScriptString().

◆ ScriptStringValidate()

HRESULT WINAPI ScriptStringValidate ( SCRIPT_STRING_ANALYSIS  ssa)

Definition at line 3865 of file usp10.c.

3866{
3867 StringAnalysis *analysis = ssa;
3868
3869 TRACE("(%p)\n", ssa);
3870
3871 if (!analysis) return E_INVALIDARG;
3873}

◆ ScriptStringXtoCP()

HRESULT WINAPI ScriptStringXtoCP ( SCRIPT_STRING_ANALYSIS  ssa,
int  iX,
int *  piCh,
int *  piTrailing 
)

Definition at line 2479 of file usp10.c.

2480{
2481 StringAnalysis* analysis = ssa;
2482 int item;
2483
2484 TRACE("(%p), %d, (%p), (%p)\n", ssa, iX, piCh, piTrailing);
2485
2486 if (!ssa || !piCh || !piTrailing) return S_FALSE;
2487 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
2488
2489 /* out of range */
2490 if(iX < 0)
2491 {
2492 if (analysis->pItem[0].a.fRTL)
2493 {
2494 *piCh = 1;
2495 *piTrailing = FALSE;
2496 }
2497 else
2498 {
2499 *piCh = -1;
2500 *piTrailing = TRUE;
2501 }
2502 return S_OK;
2503 }
2504
2505 for(item=0; item<analysis->numItems; item++)
2506 {
2507 int i;
2508 int CP;
2509
2510 for (i = 0; i < analysis->numItems && analysis->logical2visual[i] != item; i++)
2511 /* nothing */;
2512
2513 CP = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
2514 /* initialize max extents for uninitialized runs */
2515 if (analysis->glyphs[i].iMaxPosX == -1)
2516 {
2517 if (analysis->pItem[i].a.fRTL)
2518 ScriptCPtoX(0, FALSE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2519 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2520 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2521 else
2522 ScriptCPtoX(CP, TRUE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2523 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2524 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2525 }
2526
2527 if (iX > analysis->glyphs[i].iMaxPosX)
2528 {
2529 iX -= analysis->glyphs[i].iMaxPosX;
2530 continue;
2531 }
2532
2533 ScriptXtoCP(iX, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2534 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2535 &analysis->pItem[i].a, piCh, piTrailing);
2536 *piCh += analysis->pItem[i].iCharPos;
2537
2538 return S_OK;
2539 }
2540
2541 /* out of range */
2542 *piCh = analysis->pItem[analysis->numItems].iCharPos;
2543 *piTrailing = FALSE;
2544
2545 return S_OK;
2546}
HRESULT WINAPI ScriptXtoCP(int iX, int cChars, int cGlyphs, const WORD *pwLogClust, const SCRIPT_VISATTR *psva, const int *piAdvance, const SCRIPT_ANALYSIS *psa, int *piCP, int *piTrailing)
Definition: usp10.c:2858

Referenced by EDIT_CharFromPos(), and test_ScriptStringXtoCP_CPtoX().

◆ ScriptTextOut()

HRESULT WINAPI ScriptTextOut ( const HDC  hdc,
SCRIPT_CACHE *  psc,
int  x,
int  y,
UINT  fuOptions,
const RECT *  lprc,
const SCRIPT_ANALYSIS *  psa,
const WCHAR *  pwcReserved,
int  iReserved,
const WORD *  pwGlyphs,
int  cGlyphs,
const int *  piAdvance,
const int *  piJustify,
const GOFFSET *  pGoffset 
)

Definition at line 3605 of file usp10.c.

3609{
3610 HRESULT hr;
3611 INT i, dir = 1;
3612 INT *lpDx;
3613 WORD *reordered_glyphs = (WORD *)pwGlyphs;
3614
3615 TRACE("(%p, %p, %d, %d, %08x, %s, %p, %p, %d, %p, %d, %p, %p, %p)\n",
3616 hdc, psc, x, y, fuOptions, wine_dbgstr_rect(lprc), psa, pwcReserved, iReserved, pwGlyphs, cGlyphs,
3617 piAdvance, piJustify, pGoffset);
3618
3619 if (!hdc || !psc) return E_INVALIDARG;
3620 if (!piAdvance || !psa || !pwGlyphs) return E_INVALIDARG;
3621 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3622
3623 fuOptions &= ETO_CLIPPED | ETO_OPAQUE;
3624 fuOptions |= ETO_IGNORELANGUAGE;
3625 if (!psa->fNoGlyphIndex && *psc && ((ScriptCache *)*psc)->sfnt)
3626 fuOptions |= ETO_GLYPH_INDEX; /* We do actually have glyph indices */
3627
3628 if (!(lpDx = calloc(cGlyphs, 2 * sizeof(*lpDx))))
3629 return E_OUTOFMEMORY;
3630 fuOptions |= ETO_PDY;
3631
3632 if (psa->fRTL && psa->fLogicalOrder)
3633 {
3634 if (!(reordered_glyphs = calloc(cGlyphs, sizeof(*reordered_glyphs))))
3635 {
3636 free( lpDx );
3637 return E_OUTOFMEMORY;
3638 }
3639
3640 for (i = 0; i < cGlyphs; i++)
3641 reordered_glyphs[i] = pwGlyphs[cGlyphs - 1 - i];
3642 dir = -1;
3643 }
3644
3645 for (i = 0; i < cGlyphs; i++)
3646 {
3647 int orig_index = (dir > 0) ? i : cGlyphs - 1 - i;
3648 lpDx[i * 2] = piAdvance[orig_index];
3649 lpDx[i * 2 + 1] = 0;
3650
3651 if (pGoffset)
3652 {
3653 if (i == 0)
3654 {
3655 x += pGoffset[orig_index].du * dir;
3656 y += pGoffset[orig_index].dv;
3657 }
3658 else
3659 {
3660 lpDx[(i - 1) * 2] += pGoffset[orig_index].du * dir;
3661 lpDx[(i - 1) * 2 + 1] += pGoffset[orig_index].dv;
3662 }
3663 lpDx[i * 2] -= pGoffset[orig_index].du * dir;
3664 lpDx[i * 2 + 1] -= pGoffset[orig_index].dv;
3665 }
3666 }
3667
3668 if (!ExtTextOutW(hdc, x, y, fuOptions, lprc, reordered_glyphs, cGlyphs, lpDx))
3669 hr = S_FALSE;
3670
3671 if (reordered_glyphs != pwGlyphs) free( reordered_glyphs );
3672 free(lpDx);
3673
3674 return hr;
3675}
unsigned int dir
Definition: maze.c:112
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
_In_ int _Inout_ LPRECT lprc
Definition: winuser.h:4620
#define ETO_CLIPPED
Definition: wingdi.h:648
BOOL WINAPI ExtTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCWSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
#define ETO_OPAQUE
Definition: wingdi.h:647
#define ETO_PDY
Definition: wingdi.h:657

Referenced by draw_text(), SS_ItemOut(), test_ScriptTextOut(), test_ScriptTextOut2(), and test_ScriptTextOut3().

◆ ScriptXtoCP()

HRESULT WINAPI ScriptXtoCP ( int  iX,
int  cChars,
int  cGlyphs,
const WORD *  pwLogClust,
const SCRIPT_VISATTR *  psva,
const int *  piAdvance,
const SCRIPT_ANALYSIS *  psa,
int *  piCP,
int *  piTrailing 
)

Definition at line 2858 of file usp10.c.

2867{
2868 int direction = 1;
2869 int iPosX;
2870 int i;
2871 int glyph_index, cluster_index;
2872 int cluster_size;
2873
2874 TRACE("(%d,%d,%d,%p,%p,%p,%p,%p,%p)\n",
2875 iX, cChars, cGlyphs, pwLogClust, psva, piAdvance,
2876 psa, piCP, piTrailing);
2877
2878 if (psa->fRTL && ! psa->fLogicalOrder)
2879 direction = -1;
2880
2881 /* Handle an iX < 0 */
2882 if (iX < 0)
2883 {
2884 if (direction < 0)
2885 {
2886 *piCP = cChars;
2887 *piTrailing = 0;
2888 }
2889 else
2890 {
2891 *piCP = -1;
2892 *piTrailing = 1;
2893 }
2894 return S_OK;
2895 }
2896
2897 /* Looking for non-reversed clusters in a reversed string */
2898 if (direction < 0)
2899 {
2900 int max_clust = pwLogClust[0];
2901 for (i=0; i< cChars; i++)
2902 if (pwLogClust[i] > max_clust)
2903 {
2904 FIXME("We do not handle non reversed clusters properly\n");
2905 break;
2906 }
2907 }
2908
2909 /* find the glyph_index based in iX */
2910 if (direction > 0)
2911 {
2912 for (glyph_index = -1, iPosX = iX; iPosX >=0 && glyph_index < cGlyphs; iPosX -= piAdvance[glyph_index+1], glyph_index++)
2913 ;
2914 }
2915 else
2916 {
2917 for (glyph_index = -1, iPosX = iX; iPosX > 0 && glyph_index < cGlyphs; iPosX -= piAdvance[glyph_index+1], glyph_index++)
2918 ;
2919 }
2920
2921 TRACE("iPosX %i -> glyph_index %i (%i)\n", iPosX, glyph_index, cGlyphs);
2922
2923 *piTrailing = 0;
2924 if (glyph_index >= 0 && glyph_index < cGlyphs)
2925 {
2926 /* find the cluster */
2927 if (direction > 0 )
2928 for (i = 0, cluster_index = pwLogClust[0]; i < cChars && pwLogClust[i] <= glyph_index; cluster_index=pwLogClust[i++])
2929 ;
2930 else
2931 for (i = 0, cluster_index = pwLogClust[0]; i < cChars && pwLogClust[i] >= glyph_index; cluster_index=pwLogClust[i++])
2932 ;
2933
2934 TRACE("cluster_index %i\n", cluster_index);
2935
2936 if (direction < 0 && iPosX >= 0 && glyph_index != cluster_index)
2937 {
2938 /* We are off the end of the string */
2939 *piCP = -1;
2940 *piTrailing = 1;
2941 return S_OK;
2942 }
2943
2944 get_cluster_data(pwLogClust, cChars, cluster_index, &cluster_size, &i);
2945
2946 TRACE("first char index %i\n",i);
2948 {
2949 /* Check trailing */
2950 if (glyph_index != cluster_index ||
2951 (direction > 0 && abs(iPosX) <= (piAdvance[glyph_index] / 2)) ||
2952 (direction < 0 && abs(iPosX) >= (piAdvance[glyph_index] / 2)))
2953 *piTrailing = cluster_size;
2954 }
2955 else
2956 {
2957 if (cluster_size > 1)
2958 {
2959 /* Be part way through the glyph cluster based on size and position */
2960 int cluster_advance = get_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, cluster_index, direction);
2961 double cluster_part_width = cluster_advance / (float)cluster_size;
2962 double adv;
2963 int part_index;
2964
2965 /* back up to the beginning of the cluster */
2966 for (adv = iPosX, part_index = cluster_index; part_index <= glyph_index; part_index++)
2967 adv += piAdvance[part_index];
2968 if (adv > iX) adv = iX;
2969
2970 TRACE("Multi-char cluster, no snap\n");
2971 TRACE("cluster size %i, pre-cluster iPosX %f\n",cluster_size, adv);
2972 TRACE("advance %i divides into %f per char\n", cluster_advance, cluster_part_width);
2973 if (direction > 0)
2974 {
2975 for (part_index = 0; adv >= 0; adv-=cluster_part_width, part_index++)
2976 ;
2977 if (part_index) part_index--;
2978 }
2979 else
2980 {
2981 for (part_index = 0; adv > 0; adv-=cluster_part_width, part_index++)
2982 ;
2983 if (part_index > cluster_size)
2984 {
2985 adv += cluster_part_width;
2986 part_index=cluster_size;
2987 }
2988 }
2989
2990 TRACE("base_char %i part_index %i, leftover advance %f\n",i, part_index, adv);
2991
2992 if (direction > 0)
2993 i += part_index;
2994 else
2995 i += (cluster_size - part_index);
2996
2997 /* Check trailing */
2998 if ((direction > 0 && fabs(adv) <= (cluster_part_width / 2.0)) ||
2999 (direction < 0 && adv && fabs(adv) >= (cluster_part_width / 2.0)))
3000 *piTrailing = 1;
3001 }
3002 else
3003 {
3004 /* Check trailing */
3005 if ((direction > 0 && abs(iPosX) <= (piAdvance[glyph_index] / 2)) ||
3006 (direction < 0 && abs(iPosX) >= (piAdvance[glyph_index] / 2)))
3007 *piTrailing = 1;
3008 }
3009 }
3010 }
3011 else
3012 {
3013 TRACE("Point falls outside of string\n");
3014 if (glyph_index < 0)
3015 i = cChars-1;
3016 else /* (glyph_index >= cGlyphs) */
3017 i = cChars;
3018
3019 /* If not snapping in the reverse direction (such as Hebrew) Then 0
3020 point flow to the next character */
3021 if (direction < 0)
3022 {
3023 if (!scriptInformation[psa->eScript].props.fNeedsCaretInfo && abs(iPosX) == piAdvance[glyph_index])
3024 i++;
3025 else
3026 *piTrailing = 1;
3027 }
3028 }
3029
3030 *piCP = i;
3031
3032 TRACE("*piCP=%d\n", *piCP);
3033 TRACE("*piTrailing=%d\n", *piTrailing);
3034 return S_OK;
3035}
_ACRTIMP double __cdecl fabs(double)
static int get_cluster_advance(const int *piAdvance, const SCRIPT_VISATTR *psva, const WORD *pwLogClust, int cGlyphs, int cChars, int cluster, int direction)
Definition: usp10.c:2797
static BOOL get_cluster_data(const WORD *pwLogClust, int cChars, int cluster_index, int *cluster_size, int *start_index)
Definition: usp10.c:2764
#define abs(i)
Definition: fconv.c:206

Referenced by _test_caret_item_ScriptXtoCP(), _test_item_ScriptXtoX(), ME_CharFromPointContext(), ScriptStringXtoCP(), and test_ScriptXtoX().

◆ set_cache_font_properties()

static BOOL set_cache_font_properties ( const HDC  hdc,
ScriptCache *  sc 
)
inlinestatic

Definition at line 684 of file usp10.c.

685{
686 sc->sfp.cBytes = sizeof(sc->sfp);
687
688 if (!sc->sfnt)
689 {
690 sc->sfp.wgBlank = sc->tm.tmBreakChar;
691 sc->sfp.wgDefault = sc->tm.tmDefaultChar;
692 sc->sfp.wgInvalid = sc->sfp.wgBlank;
693 sc->sfp.wgKashida = 0xFFFF;
694 sc->sfp.iKashidaWidth = 0;
695 }
696 else
697 {
698 static const WCHAR chars[4] = {0x0020, 0x200B, 0xF71B, 0x0640};
699 /* U+0020: numeric space
700 U+200B: zero width space
701 U+F71B: unknown char found by black box testing
702 U+0640: kashida */
703 WORD gi[4];
704
706 {
707 if(gi[0] != 0xFFFF) /* 0xFFFF: index of default non exist char */
708 sc->sfp.wgBlank = gi[0];
709 else
710 sc->sfp.wgBlank = 0;
711
712 sc->sfp.wgDefault = 0;
713
714 if (gi[2] != 0xFFFF)
715 sc->sfp.wgInvalid = gi[2];
716 else if (gi[1] != 0xFFFF)
717 sc->sfp.wgInvalid = gi[1];
718 else if (gi[0] != 0xFFFF)
719 sc->sfp.wgInvalid = gi[0];
720 else
721 sc->sfp.wgInvalid = 0;
722
723 sc->sfp.wgKashida = gi[3];
724
725 sc->sfp.iKashidaWidth = 0; /* TODO */
726 }
727 else
728 return FALSE;
729 }
730 return TRUE;
731}
WCHAR tmBreakChar
Definition: wingdi.h:2843
WCHAR tmDefaultChar
Definition: wingdi.h:2842

Referenced by init_script_cache().

◆ set_cache_glyph()

static WORD set_cache_glyph ( SCRIPT_CACHE *  psc,
WCHAR  c,
WORD  glyph 
)
inlinestatic

Definition at line 759 of file usp10.c.

760{
761 CacheGlyphPage **page = &((ScriptCache *)*psc)->page[c / 0x10000];
762 WORD **block;
763 if (!*page && !(*page = calloc(1, sizeof(CacheGlyphPage)))) return 0;
764
765 block = &(*page)->glyphs[(c % 0x10000) >> GLYPH_BLOCK_SHIFT];
766 if (!*block && !(*block = calloc(GLYPH_BLOCK_SIZE, sizeof(WORD)))) return 0;
767 return ((*block)[(c % 0x10000) & GLYPH_BLOCK_MASK] = glyph);
768}

Referenced by ScriptGetCMap(), and ScriptShapeOpenType().

◆ set_cache_glyph_widths()

static BOOL set_cache_glyph_widths ( SCRIPT_CACHE *  psc,
WORD  glyph,
ABC *  abc 
)
inlinestatic

Definition at line 780 of file usp10.c.

781{
782 ABC **block = &((ScriptCache *)*psc)->widths[glyph >> GLYPH_BLOCK_SHIFT];
783
784 if (!*block && !(*block = calloc(GLYPH_BLOCK_SIZE, sizeof(ABC)))) return FALSE;
785 memcpy(&(*block)[glyph & GLYPH_BLOCK_MASK], abc, sizeof(ABC));
786 return TRUE;
787}

Referenced by ScriptGetGlyphABCWidth(), and ScriptPlaceOpenType().

◆ SS_ItemOut()

static HRESULT SS_ItemOut ( SCRIPT_STRING_ANALYSIS  ssa,
int  iX,
int  iY,
int  iItem,
int  cStart,
int  cEnd,
UINT  uOptions,
const RECT *  prc,
BOOL  fSelected,
BOOL  fDisabled 
)
static

Definition at line 2204 of file usp10.c.

2214{
2215 StringAnalysis *analysis;
2216 int off_x = 0;
2217 HRESULT hr;
2218 COLORREF BkColor = 0x0;
2219 COLORREF TextColor = 0x0;
2220 INT BkMode = 0;
2221 INT runStart, runEnd;
2222 INT iGlyph, cGlyphs;
2223 HFONT oldFont = 0x0;
2224 RECT crc;
2225 int i;
2226
2227 TRACE("(%p,%d,%d,%d,%d,%d, 0x%1x, %d, %d)\n",
2228 ssa, iX, iY, iItem, cStart, cEnd, uOptions, fSelected, fDisabled);
2229
2230 if (!(analysis = ssa)) return E_INVALIDARG;
2231
2232 if ((cStart >= 0 && analysis->pItem[iItem+1].iCharPos <= cStart) ||
2233 (cEnd >= 0 && analysis->pItem[iItem].iCharPos >= cEnd))
2234 return S_OK;
2235
2236 if (prc)
2237 memcpy(&crc, prc, sizeof(crc));
2238 if (fSelected)
2239 {
2240 BkMode = GetBkMode(analysis->hdc);
2241 SetBkMode( analysis->hdc, OPAQUE);
2242 BkColor = GetBkColor(analysis->hdc);
2244 if (!fDisabled)
2245 {
2246 TextColor = GetTextColor(analysis->hdc);
2248 }
2249 }
2250 if (analysis->glyphs[iItem].fallbackFont)
2251 oldFont = SelectObject(analysis->hdc, analysis->glyphs[iItem].fallbackFont);
2252
2253 if (cStart >= 0 && analysis->pItem[iItem+1].iCharPos > cStart && analysis->pItem[iItem].iCharPos <= cStart)
2254 runStart = cStart - analysis->pItem[iItem].iCharPos;
2255 else
2256 runStart = 0;
2257 if (cEnd >= 0 && analysis->pItem[iItem+1].iCharPos > cEnd && analysis->pItem[iItem].iCharPos <= cEnd)
2258 runEnd = (cEnd-1) - analysis->pItem[iItem].iCharPos;
2259 else
2260 runEnd = (analysis->pItem[iItem+1].iCharPos - analysis->pItem[iItem].iCharPos) - 1;
2261
2262 if (analysis->pItem[iItem].a.fRTL)
2263 {
2264 if (cEnd >= 0 && cEnd < analysis->pItem[iItem+1].iCharPos)
2265 ScriptStringCPtoX(ssa, cEnd, FALSE, &off_x);
2266 else
2267 ScriptStringCPtoX(ssa, analysis->pItem[iItem+1].iCharPos-1, TRUE, &off_x);
2268 crc.left = iX + off_x;
2269 }
2270 else
2271 {
2272 if (cStart >=0 && runStart)
2273 ScriptStringCPtoX(ssa, cStart, FALSE, &off_x);
2274 else
2275 ScriptStringCPtoX(ssa, analysis->pItem[iItem].iCharPos, FALSE, &off_x);
2276 crc.left = iX + off_x;
2277 }
2278
2279 if (analysis->pItem[iItem].a.fRTL)
2280 iGlyph = analysis->glyphs[iItem].pwLogClust[runEnd];
2281 else
2282 iGlyph = analysis->glyphs[iItem].pwLogClust[runStart];
2283
2284 if (analysis->pItem[iItem].a.fRTL)
2285 cGlyphs = analysis->glyphs[iItem].pwLogClust[runStart] - iGlyph;
2286 else
2287 cGlyphs = analysis->glyphs[iItem].pwLogClust[runEnd] - iGlyph;
2288
2289 cGlyphs++;
2290
2291 /* adjust for cluster glyphs when starting */
2292 if (analysis->pItem[iItem].a.fRTL)
2293 i = analysis->pItem[iItem+1].iCharPos - 1;
2294 else
2295 i = analysis->pItem[iItem].iCharPos;
2296
2297 for (; i >=analysis->pItem[iItem].iCharPos && i < analysis->pItem[iItem+1].iCharPos; (analysis->pItem[iItem].a.fRTL)?i--:i++)
2298 {
2299 if (analysis->glyphs[iItem].pwLogClust[i - analysis->pItem[iItem].iCharPos] == iGlyph)
2300 {
2301 if (analysis->pItem[iItem].a.fRTL)
2302 ScriptStringCPtoX(ssa, i, TRUE, &off_x);
2303 else
2304 ScriptStringCPtoX(ssa, i, FALSE, &off_x);
2305 break;
2306 }
2307 }
2308
2309 if (cEnd < 0 || scriptInformation[analysis->pItem[iItem].a.eScript].props.fNeedsCaretInfo)
2310 {
2311 INT direction;
2312 INT clust_glyph;
2313
2314 clust_glyph = iGlyph + cGlyphs;
2315 if (analysis->pItem[iItem].a.fRTL)
2316 direction = -1;
2317 else
2318 direction = 1;
2319
2320 while(clust_glyph < analysis->glyphs[iItem].numGlyphs &&
2321 !does_glyph_start_cluster(analysis->glyphs[iItem].psva, analysis->glyphs[iItem].pwLogClust, (analysis->pItem[iItem+1].iCharPos - analysis->pItem[iItem].iCharPos), clust_glyph, direction))
2322 {
2323 cGlyphs++;
2324 clust_glyph++;
2325 }
2326 }
2327
2328 hr = ScriptTextOut(analysis->hdc,
2329 (SCRIPT_CACHE *)&analysis->glyphs[iItem].sc, iX + off_x,
2330 iY, uOptions, &crc, &analysis->pItem[iItem].a, NULL, 0,
2331 &analysis->glyphs[iItem].glyphs[iGlyph], cGlyphs,
2332 &analysis->glyphs[iItem].piAdvance[iGlyph], NULL,
2333 &analysis->glyphs[iItem].pGoffset[iGlyph]);
2334
2335 TRACE("ScriptTextOut hr=%08lx\n", hr);
2336
2337 if (fSelected)
2338 {
2339 SetBkColor(analysis->hdc, BkColor);
2340 SetBkMode( analysis->hdc, BkMode);
2341 if (!fDisabled)
2342 SetTextColor(analysis->hdc, TextColor);
2343 }
2344 if (analysis->glyphs[iItem].fallbackFont)
2345 SelectObject(analysis->hdc, oldFont);
2346
2347 return hr;
2348}
HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrailing, int *pX)
Definition: usp10.c:2416
HRESULT WINAPI ScriptTextOut(const HDC hdc, SCRIPT_CACHE *psc, int x, int y, UINT fuOptions, const RECT *lprc, const SCRIPT_ANALYSIS *psa, const WCHAR *pwcReserved, int iReserved, const WORD *pwGlyphs, int cGlyphs, const int *piAdvance, const int *piJustify, const GOFFSET *pGoffset)
Definition: usp10.c:3605
#define COLOR_HIGHLIGHT
Definition: winuser.h:937
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:938
Definition: dcommon.idl:28
long left
Definition: dcommon.idl:29
DWORD COLORREF
Definition: windef.h:100
#define NtUserGetSysColor(A)
Definition: wine-compat.h:5
int WINAPI GetBkMode(_In_ HDC)
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
COLORREF WINAPI GetTextColor(_In_ HDC)
Definition: text.c:860
COLORREF WINAPI GetBkColor(_In_ HDC)
Definition: dc.c:978
#define OPAQUE
Definition: wingdi.h:949
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1056
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:917

Referenced by ScriptStringOut().

◆ usp10_array_reserve()

BOOL usp10_array_reserve ( void **  elements,
SIZE_T *  capacity,
SIZE_T  count,
SIZE_T  size 
)

Definition at line 655 of file usp10.c.

656{
657 SIZE_T max_capacity, new_capacity;
658 void *new_elements;
659
660 if (count <= *capacity)
661 return TRUE;
662
663 max_capacity = ~(SIZE_T)0 / size;
664 if (count > max_capacity)
665 return FALSE;
666
667 new_capacity = max(1, *capacity);
668 while (new_capacity < count && new_capacity <= max_capacity / 2)
669 new_capacity *= 2;
670 if (new_capacity < count)
671 new_capacity = count;
672
673 new_elements = realloc(*elements, new_capacity * size);
674 if (!new_elements)
675 return FALSE;
676 memset( (char *)new_elements + *capacity * size, 0, (new_capacity - *capacity) * size );
677
678 *elements = new_elements;
679 *capacity = new_capacity;
680 return TRUE;
681}
#define max(a, b)
Definition: svc.c:63
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by computeBracketPairs(), usp10_language_add_feature_list(), usp10_script_add_language(), and usp10_script_cache_add_script().

◆ usp10_compare_script_range()

static int __cdecl usp10_compare_script_range ( const void *  key,
const void *  value 
)
static

Definition at line 929 of file usp10.c.

930{
931 const struct usp10_script_range *range = value;
932 const DWORD *ch = key;
933
934 if (*ch < range->rangeFirst)
935 return -1;
936 if (*ch > range->rangeLast)
937 return 1;
938 return 0;
939}
Definition: copy.c:22
DWORD rangeFirst
Definition: usp10.c:59

Referenced by get_char_script().

◆ USP10_FindGlyphInLogClust()

int USP10_FindGlyphInLogClust ( const WORD *  pwLogClust,
int  cChars,
WORD  target 
)

Definition at line 1015 of file usp10.c.

1016{
1017 FindGlyph_struct fgs;
1018 WORD *ptr;
1019 INT k;
1020
1021 if (pwLogClust[0] < pwLogClust[cChars-1])
1022 fgs.ascending = TRUE;
1023 else
1024 fgs.ascending = FALSE;
1025
1026 fgs.target = target;
1027 ptr = bsearch(&fgs, pwLogClust, cChars, sizeof(WORD), compare_FindGlyph);
1028
1029 if (!ptr)
1030 return -1;
1031
1032 for (k = (ptr - pwLogClust)-1; k >= 0 && pwLogClust[k] == target; k--)
1033 ;
1034 k++;
1035
1036 return k;
1037}
static int __cdecl compare_FindGlyph(const void *a, const void *b)
Definition: usp10.c:999
static PVOID ptr
Definition: dispmode.c:27
BOOL ascending
Definition: usp10.c:651
Definition: tools.h:99

Referenced by does_glyph_start_cluster(), OpenType_GDEF_UpdateGlyphProps(), ShapeCharGlyphProp_Arabic(), ShapeCharGlyphProp_BaseIndic(), ShapeCharGlyphProp_Default(), ShapeCharGlyphProp_Hebrew(), ShapeCharGlyphProp_None(), ShapeCharGlyphProp_Thai(), ShapeCharGlyphProp_Tibet(), and UpdateClusters().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( uniscribe  )

Variable Documentation

◆ cs_script_cache

static CRITICAL_SECTION cs_script_cache = { &cs_script_cache_dbg, -1, 0, 0, 0, 0 }
static

Definition at line 606 of file usp10.c.

Referenced by init_script_cache(), and ScriptFreeCache().

◆ cs_script_cache_dbg

CRITICAL_SECTION_DEBUG cs_script_cache_dbg
static
Initial value:
=
{
0, 0, { (DWORD_PTR)(__FILE__ ": script_cache") }
}
static CRITICAL_SECTION_DEBUG cs_script_cache_dbg
Definition: usp10.c:607
#define DWORD_PTR
Definition: treelist.c:76

Definition at line 607 of file usp10.c.

◆ script_cache_list

struct list script_cache_list = LIST_INIT(script_cache_list)
static

Definition at line 614 of file usp10.c.

Referenced by init_script_cache().

◆ script_props

const SCRIPT_PROPERTIES* script_props[]
static

Definition at line 561 of file usp10.c.

Referenced by ScriptGetProperties().

◆ script_ranges

const struct usp10_script_range script_ranges[]
static

Referenced by get_char_script().

◆ scriptInformation