ReactOS 0.4.17-dev-966-gf06eace
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 1268 of file usp10.c.

1272{
1273
1274#define Numeric_space 0x0020
1275#define ZWSP 0x200B
1276#define ZWNJ 0x200C
1277#define ZWJ 0x200D
1278
1279 enum usp10_script last_indic = Script_Undefined;
1280 int cnt = 0, index = 0, str = 0;
1281 enum usp10_script New_Script = -1;
1282 int i;
1283 WORD *levels = NULL;
1284 WORD *layout_levels = NULL;
1285 WORD *overrides = NULL;
1286 WORD *strength = NULL;
1287 enum usp10_script *scripts;
1288 WORD baselevel = 0;
1289 WORD baselayout = 0;
1290 BOOL new_run;
1291 WORD layoutRTL = 0;
1292 BOOL forceLevels = FALSE;
1293 unsigned int consumed = 0;
1295
1296 TRACE("%s,%d,%d,%p,%p,%p,%p\n", debugstr_wn(pwcInChars, cInChars), cInChars, cMaxItems,
1297 psControl, psState, pItems, pcItems);
1298
1299 if (!pwcInChars || !cInChars || !pItems || cMaxItems < 2)
1300 return E_INVALIDARG;
1301
1302 if (!(scripts = calloc(cInChars, sizeof(*scripts))))
1303 return E_OUTOFMEMORY;
1304
1305 for (i = 0; i < cInChars; i++)
1306 {
1307 if (!consumed)
1308 {
1309 scripts[i] = get_char_script(pwcInChars,i,cInChars,&consumed);
1310 consumed --;
1311 }
1312 else
1313 {
1314 scripts[i] = scripts[i-1];
1315 consumed --;
1316 }
1317 /* Devanagari danda (U+0964) and double danda (U+0965) are used for
1318 all Indic scripts */
1319 if ((pwcInChars[i] == 0x964 || pwcInChars[i] ==0x965) && last_indic != Script_Undefined)
1320 scripts[i] = last_indic;
1321 else if (is_indic(scripts[i]))
1322 last_indic = base_indic(scripts[i]);
1323
1324 /* Some unicode points :
1325 (Zero Width Space U+200B - Right-to-Left Mark U+200F)
1326 (Left Right Embed U+202A - Left Right Override U+202D)
1327 (Left Right Isolate U+2066 - Pop Directional Isolate U+2069)
1328 will force us into bidi mode */
1329 if (!forceLevels && ((pwcInChars[i] >= 0x200B && pwcInChars[i] <= 0x200F) ||
1330 (pwcInChars[i] >= 0x202A && pwcInChars[i] <= 0x202E) ||
1331 (pwcInChars[i] >= 0x2066 && pwcInChars[i] <= 0x2069)))
1332
1333 forceLevels = TRUE;
1334
1335 /* Diacritical marks merge with other scripts */
1336 if (scripts[i] == Script_Diacritical)
1337 {
1338 if (i > 0)
1339 {
1340 if (pScriptTags)
1341 scripts[i] = scripts[i-1];
1342 else
1343 {
1344 int j;
1345 BOOL asian = FALSE;
1346 enum usp10_script first_script = scripts[i-1];
1347 for (j = i-1; j >= 0 && scripts[j] == first_script && pwcInChars[j] != Numeric_space; j--)
1348 {
1349 enum usp10_script original = scripts[j];
1350 if (original == Script_Ideograph || original == Script_Kana || original == Script_Yi || original == Script_CJK_Han || original == Script_Bopomofo)
1351 {
1352 asian = TRUE;
1353 break;
1354 }
1355 if (original != Script_MathAlpha && scriptInformation[scripts[j]].props.fComplex)
1356 break;
1357 scripts[j] = scripts[i];
1358 if (original == Script_Punctuation2)
1359 break;
1360 }
1361 if (j >= 0 && (scriptInformation[scripts[j]].props.fComplex || asian))
1362 scripts[i] = scripts[j];
1363 }
1364 }
1365 }
1366 }
1367
1368 for (i = 0; i < cInChars; i++)
1369 {
1370 /* Joiners get merged preferencially right */
1371 if (i > 0 && (pwcInChars[i] == ZWJ || pwcInChars[i] == ZWNJ || pwcInChars[i] == ZWSP))
1372 {
1373 int j;
1374 if (i+1 == cInChars)
1375 scripts[i] = scripts[i-1];
1376 else
1377 {
1378 for (j = i+1; j < cInChars; j++)
1379 {
1380 if (pwcInChars[j] != ZWJ && pwcInChars[j] != ZWNJ
1381 && pwcInChars[j] != ZWSP && pwcInChars[j] != Numeric_space)
1382 {
1383 scripts[i] = scripts[j];
1384 break;
1385 }
1386 }
1387 }
1388 }
1389 }
1390
1391 if (psState && psControl)
1392 {
1393 if (!(levels = calloc(cInChars, sizeof(*levels))))
1394 goto nomemory;
1395
1396 if (!(overrides = calloc(cInChars, sizeof(*overrides))))
1397 goto nomemory;
1398
1399 if (!(layout_levels = calloc(cInChars, sizeof(*layout_levels))))
1400 goto nomemory;
1401
1402 if (psState->fOverrideDirection)
1403 {
1404 if (!forceLevels)
1405 {
1406 SCRIPT_STATE s = *psState;
1408 BIDI_DetermineLevels(pwcInChars, cInChars, &s, psControl, layout_levels, overrides);
1409 if (odd(layout_levels[0]))
1410 forceLevels = TRUE;
1411 else for (i = 0; i < cInChars; i++)
1412 if (layout_levels[i]!=layout_levels[0])
1413 {
1414 forceLevels = TRUE;
1415 break;
1416 }
1417 }
1418
1419 BIDI_DetermineLevels(pwcInChars, cInChars, psState, psControl, levels, overrides);
1420 }
1421 else
1422 {
1423 BIDI_DetermineLevels(pwcInChars, cInChars, psState, psControl, levels, overrides);
1424 memcpy(layout_levels, levels, cInChars * sizeof(WORD));
1425 }
1426 baselevel = levels[0];
1427 baselayout = layout_levels[0];
1428 for (i = 0; i < cInChars; i++)
1429 if (levels[i]!=levels[0])
1430 break;
1431 if (i >= cInChars && !odd(baselevel) && !odd(psState->uBidiLevel) && !forceLevels)
1432 {
1433 free(levels);
1434 free(overrides);
1435 free(layout_levels);
1436 overrides = NULL;
1437 levels = NULL;
1438 layout_levels = NULL;
1439 }
1440 else
1441 {
1442 if (!(strength = calloc(cInChars, sizeof(*strength))))
1443 goto nomemory;
1444 BIDI_GetStrengths(pwcInChars, cInChars, psControl, strength);
1445
1446 /* We currently mis-level leading Diacriticals */
1447 if (scripts[0] == Script_Diacritical)
1448 for (i = 0; i < cInChars && scripts[0] == Script_Diacritical; i++)
1449 {
1450 levels[i] = odd(levels[i])?levels[i]+1:levels[i];
1451 strength[i] = BIDI_STRONG;
1452 }
1453
1454 /* Math punctuation bordered on both sides by numbers can be
1455 merged into the number */
1456 for (i = 0; i < cInChars; i++)
1457 {
1458 if (i > 0 && i < cInChars-1 &&
1459 script_is_numeric(scripts[i-1]) &&
1460 wcschr(L"#$%+,-./:\x2212\x2044\x00a0", pwcInChars[i]))
1461 {
1462 if (script_is_numeric(scripts[i+1]))
1463 {
1464 scripts[i] = scripts[i+1];
1465 levels[i] = levels[i-1];
1466 strength[i] = strength[i-1];
1467 i++;
1468 }
1469 else if (wcschr(L"#$%+-/\x2212\x2044", pwcInChars[i]))
1470 {
1471 int j;
1472 for (j = i+1; j < cInChars; j++)
1473 {
1474 if (script_is_numeric(scripts[j]))
1475 {
1476 for(;i<j; i++)
1477 {
1478 scripts[i] = scripts[j];
1479 levels[i] = levels[i-1];
1480 strength[i] = strength[i-1];
1481 }
1482 }
1483 else if (pwcInChars[i] != pwcInChars[j]) break;
1484 }
1485 }
1486 }
1487 }
1488
1489 for (i = 0; i < cInChars; i++)
1490 {
1491 /* Numerics at level 0 get bumped to level 2 */
1492 if (!overrides[i] && (levels[i] == 0 || (odd(psState->uBidiLevel)
1493 && levels[i] == psState->uBidiLevel + 1)) && script_is_numeric(scripts[i]))
1494 {
1495 levels[i] = 2;
1496 }
1497
1498 /* Joiners get merged preferencially right */
1499 if (i > 0 && (pwcInChars[i] == ZWJ || pwcInChars[i] == ZWNJ || pwcInChars[i] == ZWSP))
1500 {
1501 int j;
1502 if (i+1 == cInChars && levels[i-1] == levels[i])
1503 strength[i] = strength[i-1];
1504 else
1505 for (j = i+1; j < cInChars && levels[i] == levels[j]; j++)
1506 if (pwcInChars[j] != ZWJ && pwcInChars[j] != ZWNJ
1507 && pwcInChars[j] != ZWSP && pwcInChars[j] != Numeric_space)
1508 {
1509 strength[i] = strength[j];
1510 break;
1511 }
1512 }
1513 }
1514 if (psControl->fMergeNeutralItems)
1515 {
1516 /* Merge the neutrals */
1517 for (i = 0; i < cInChars; i++)
1518 {
1519 if (strength[i] == BIDI_NEUTRAL || strength[i] == BIDI_WEAK)
1520 {
1521 int j;
1522 for (j = i; j > 0; j--)
1523 {
1524 if (levels[i] != levels[j])
1525 break;
1526 if ((strength[j] == BIDI_STRONG) || (strength[i] == BIDI_NEUTRAL && strength[j] == BIDI_WEAK))
1527 {
1528 scripts[i] = scripts[j];
1529 strength[i] = strength[j];
1530 break;
1531 }
1532 }
1533 }
1534 /* Try going the other way */
1535 if (strength[i] == BIDI_NEUTRAL || strength[i] == BIDI_WEAK)
1536 {
1537 int j;
1538 for (j = i; j < cInChars; j++)
1539 {
1540 if (levels[i] != levels[j])
1541 break;
1542 if ((strength[j] == BIDI_STRONG) || (strength[i] == BIDI_NEUTRAL && strength[j] == BIDI_WEAK))
1543 {
1544 scripts[i] = scripts[j];
1545 strength[i] = strength[j];
1546 break;
1547 }
1548 }
1549 }
1550 }
1551 }
1552 }
1553 }
1554
1555 while ((!levels || (levels && cnt+1 < cInChars && levels[cnt+1] == levels[0]))
1556 && (cnt < cInChars && pwcInChars[cnt] == Numeric_space))
1557 cnt++;
1558
1559 if (cnt == cInChars) /* All Spaces */
1560 {
1561 cnt = 0;
1562 New_Script = scripts[cnt];
1563 }
1564
1565 pItems[index].iCharPos = 0;
1566 pItems[index].a = scriptInformation[scripts[cnt]].a;
1567 if (pScriptTags)
1568 pScriptTags[index] = scriptInformation[scripts[cnt]].scriptTag;
1569
1570 if (strength && strength[cnt] == BIDI_STRONG)
1571 str = strength[cnt];
1572 else if (strength)
1573 str = strength[0];
1574
1575 cnt = 0;
1576
1577 if (levels)
1578 {
1579 if (strength[cnt] == BIDI_STRONG)
1580 layoutRTL = odd(layout_levels[cnt]);
1581 else
1582 layoutRTL = (psState->uBidiLevel || odd(layout_levels[cnt]));
1583 if (overrides)
1584 pItems[index].a.s.fOverrideDirection = (overrides[cnt] != 0);
1585 pItems[index].a.fRTL = odd(levels[cnt]);
1586 if (script_is_numeric(pItems[index].a.eScript))
1587 pItems[index].a.fLayoutRTL = layoutRTL;
1588 else
1589 pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
1590 pItems[index].a.s.uBidiLevel = levels[cnt];
1591 }
1592 else if (!pItems[index].a.s.uBidiLevel || (overrides && overrides[cnt]))
1593 {
1594 if (pItems[index].a.s.uBidiLevel != baselevel)
1595 pItems[index].a.s.fOverrideDirection = TRUE;
1596 layoutRTL = odd(baselayout);
1597 pItems[index].a.s.uBidiLevel = baselevel;
1598 pItems[index].a.fRTL = odd(baselevel);
1599 if (script_is_numeric(pItems[index].a.eScript))
1600 pItems[index].a.fLayoutRTL = odd(baselayout);
1601 else
1602 pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
1603 }
1604
1605 TRACE("New_Level=%i New_Strength=%i New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n",
1606 levels?levels[cnt]:-1, str, New_Script, pItems[index].a.eScript, index, cnt,
1607 pItems[index].iCharPos);
1608
1609 for (cnt=1; cnt < cInChars; cnt++)
1610 {
1611 if(pwcInChars[cnt] != Numeric_space)
1612 New_Script = scripts[cnt];
1613 else if (levels)
1614 {
1615 int j = 1;
1616 while (cnt + j < cInChars - 1 && pwcInChars[cnt+j] == Numeric_space && levels[cnt] == levels[cnt+j])
1617 j++;
1618 if (cnt + j < cInChars && levels[cnt] == levels[cnt+j])
1619 New_Script = scripts[cnt+j];
1620 else
1621 New_Script = scripts[cnt];
1622 }
1623
1624 new_run = FALSE;
1625 /* merge space strengths*/
1626 if (strength && strength[cnt] == BIDI_STRONG && str != BIDI_STRONG && New_Script == pItems[index].a.eScript)
1627 str = BIDI_STRONG;
1628
1629 if (strength && strength[cnt] == BIDI_NEUTRAL && str == BIDI_STRONG && pwcInChars[cnt] != Numeric_space && New_Script == pItems[index].a.eScript)
1630 str = BIDI_NEUTRAL;
1631
1632 /* changes in level */
1633 if (levels && (levels[cnt] != pItems[index].a.s.uBidiLevel))
1634 {
1635 TRACE("Level break(%i/%i)\n",pItems[index].a.s.uBidiLevel,levels[cnt]);
1636 new_run = TRUE;
1637 }
1638 /* changes in strength */
1639 else if (strength && pwcInChars[cnt] != Numeric_space && str != strength[cnt])
1640 {
1641 TRACE("Strength break (%i/%i)\n",str,strength[cnt]);
1642 new_run = TRUE;
1643 }
1644 /* changes in script */
1645 else if (((pwcInChars[cnt] != Numeric_space) && (New_Script != -1) && (New_Script != pItems[index].a.eScript)) || (New_Script == Script_Control))
1646 {
1647 TRACE("Script break(%i/%i)\n",pItems[index].a.eScript,New_Script);
1648 new_run = TRUE;
1649 }
1650
1651 if (!new_run && strength && str == BIDI_STRONG)
1652 {
1653 layoutRTL = odd(layout_levels[cnt]);
1654 if (script_is_numeric(pItems[index].a.eScript))
1655 pItems[index].a.fLayoutRTL = layoutRTL;
1656 }
1657
1658 if (new_run)
1659 {
1660 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);
1661
1662 index++;
1663 if (index+1 > cMaxItems)
1664 goto nomemory;
1665
1666 if (strength)
1667 str = strength[cnt];
1668
1669 pItems[index].iCharPos = cnt;
1670 memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
1671
1672 pItems[index].a = scriptInformation[New_Script].a;
1673 if (pScriptTags)
1674 pScriptTags[index] = scriptInformation[New_Script].scriptTag;
1675 if (levels)
1676 {
1677 if (overrides)
1678 pItems[index].a.s.fOverrideDirection = (overrides[cnt] != 0);
1679 if (layout_levels[cnt] == 0)
1680 layoutRTL = 0;
1681 else
1682 layoutRTL = (layoutRTL || odd(layout_levels[cnt]));
1683 pItems[index].a.fRTL = odd(levels[cnt]);
1684 if (script_is_numeric(pItems[index].a.eScript))
1685 pItems[index].a.fLayoutRTL = layoutRTL;
1686 else
1687 pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
1688 pItems[index].a.s.uBidiLevel = levels[cnt];
1689 }
1690 else if (!pItems[index].a.s.uBidiLevel || (overrides && overrides[cnt]))
1691 {
1692 if (pItems[index].a.s.uBidiLevel != baselevel)
1693 pItems[index].a.s.fOverrideDirection = TRUE;
1694 pItems[index].a.s.uBidiLevel = baselevel;
1695 pItems[index].a.fRTL = odd(baselevel);
1696 if (script_is_numeric(pItems[index].a.eScript))
1697 pItems[index].a.fLayoutRTL = layoutRTL;
1698 else
1699 pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
1700 }
1701
1702 TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos);
1703 }
1704 }
1705
1706 /* While not strictly necessary according to the spec, make sure the n+1
1707 * item is set up to prevent random behaviour if the caller erroneously
1708 * checks the n+1 structure */
1709 index++;
1710 if (index + 1 > cMaxItems) goto nomemory;
1711 memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
1712
1713 TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos);
1714
1715 /* Set one SCRIPT_STATE item being returned */
1716 if (pcItems) *pcItems = index;
1717
1718 /* Set SCRIPT_ITEM */
1719 pItems[index].iCharPos = cnt; /* the last item contains the ptr to the lastchar */
1720 res = S_OK;
1721nomemory:
1722 free(levels);
1723 free(overrides);
1724 free(layout_levels);
1725 free(strength);
1726 free(scripts);
1727 return res;
1728}
#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:1263
static BOOL is_indic(enum usp10_script script)
Definition: usp10.c:1229
static enum usp10_script base_indic(enum usp10_script script)
Definition: usp10.c:1234
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:893
#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 1234 of file usp10.c.

1235{
1236 switch (script)
1237 {
1238 case Script_Devanagari:
1240 case Script_Bengali:
1243 case Script_Gurmukhi:
1245 case Script_Gujarati:
1248 case Script_Oriya:
1250 case Script_Tamil:
1252 case Script_Telugu:
1254 case Script_Kannada:
1256 case Script_Malayalam:
1258 default:
1259 return Script_Undefined;
1260 };
1261}
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 951 of file usp10.c.

952{
954 const WORD *idx= (WORD*)b;
955 int rc = 0;
956
957 if ( find->target > *idx)
958 rc = 1;
959 else if (find->target < *idx)
960 rc = -1;
961
962 if (!find->ascending)
963 rc *= -1;
964 return rc;
965}
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 870 of file usp10.c.

871{
872 if (index < end-1 && IS_SURROGATE_PAIR(str[index],str[index+1]))
873 {
874 DWORD ch = 0x10000 + ((str[index] - 0xd800) << 10) + (str[index+1] - 0xdc00);
875 TRACE("Surrogate Pair %x %x => %lx\n",str[index], str[index+1], ch);
876 return ch;
877 }
878 return 0;
879}
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 2146 of file usp10.c.

2147{
2148 if (pva[glyph].fClusterStart)
2149 return TRUE;
2150 if (USP10_FindGlyphInLogClust(pwLogClust, cChars, glyph) >= 0)
2151 return TRUE;
2152
2153 return FALSE;
2154}
int USP10_FindGlyphInLogClust(const WORD *pwLogClust, int cChars, WORD target)
Definition: usp10.c:967
_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 1882 of file usp10.c.

1883{
1884 HKEY hkey;
1885
1886 if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Uniscribe\\Fallback", &hkey))
1887 {
1888 WCHAR value[10];
1889 DWORD count = LF_FACESIZE * sizeof(WCHAR);
1890 DWORD type;
1891
1892 swprintf(value, ARRAY_SIZE(value), L"%x", scriptInformation[scriptid].scriptTag);
1893 if (RegQueryValueExW(hkey, value, 0, &type, (BYTE *)FaceName, &count))
1894 lstrcpyW(FaceName,scriptInformation[scriptid].fallbackFont);
1895 RegCloseKey(hkey);
1896 }
1897 else
1898 lstrcpyW(FaceName,scriptInformation[scriptid].fallbackFont);
1899}
#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
#define swprintf
Definition: precomp.h:40
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 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 893 of file usp10.c.

895{
897 WORD type = 0, type2 = 0;
898 DWORD ch;
899
900 *consumed = 1;
901
902 if (str[index] == 0xc || str[index] == 0x20 || str[index] == 0x202f)
903 return Script_CR;
904
905 /* These punctuation characters are separated out as Latin punctuation */
906 if (wcschr(L"#$&',;<>?@\\^_`{|}~\x00a0", str[index]))
907 return Script_Punctuation2;
908
909 /* These chars are itemized as Punctuation by Windows */
910 if (str[index] == 0x2212 || str[index] == 0x2044)
911 return Script_Punctuation;
912
913 /* Currency Symbols by Unicode point */
914 switch (str[index])
915 {
916 case 0x09f2:
917 case 0x09f3: return Script_Bengali_Currency;
918 case 0x0af1: return Script_Gujarati_Currency;
919 case 0x0e3f: return Script_Thai_Currency;
920 case 0x20aa: return Script_Hebrew_Currency;
921 case 0x20ab: return Script_Vietnamese_Currency;
922 case 0xfb29: return Script_Hebrew_Currency;
923 }
924
926 GetStringTypeW(CT_CTYPE2, &str[index], 1, &type2);
927
928 if (type == 0)
929 return SCRIPT_UNDEFINED;
930
931 if (type & C1_CNTRL)
932 return Script_Control;
933
935 if (ch)
936 *consumed = 2;
937 else
938 ch = str[index];
939
943
944 if (range->numericScript && (type & C1_DIGIT || type2 == C2_ARABICNUMBER))
945 return range->numericScript;
946 if (range->punctScript && type & C1_PUNCT)
947 return range->punctScript;
948 return range->script;
949}
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:870
static int __cdecl usp10_compare_script_range(const void *key, const void *value)
Definition: usp10.c:881
#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 2749 of file usp10.c.

2753{
2754 int glyph_start;
2755 int glyph_end;
2756 int i, advance;
2757
2758 if (direction > 0)
2759 i = 0;
2760 else
2761 i = (cChars - 1);
2762
2763 for (glyph_start = -1, glyph_end = -1; i < cChars && i >= 0 && (glyph_start < 0 || glyph_end < 0); i+=direction)
2764 {
2765 if (glyph_start < 0 && pwLogClust[i] != cluster) continue;
2766 if (pwLogClust[i] == cluster && glyph_start < 0) glyph_start = pwLogClust[i];
2767 if (glyph_start >= 0 && glyph_end < 0 && pwLogClust[i] != cluster) glyph_end = pwLogClust[i];
2768 }
2769 if (glyph_end < 0)
2770 {
2771 if (direction > 0)
2772 glyph_end = cGlyphs;
2773 else
2774 {
2775 /* Don't fully understand multi-glyph reversed clusters yet,
2776 * do they occur for real or just in our test? */
2777 FIXME("multi-glyph reversed clusters found\n");
2778 glyph_end = glyph_start + 1;
2779 }
2780 }
2781
2782 /* Check for fClusterStart, finding this generally would mean a malformed set of data */
2783 for (i = glyph_start+1; i< glyph_end; i++)
2784 {
2785 if (psva[i].fClusterStart)
2786 {
2787 glyph_end = i;
2788 break;
2789 }
2790 }
2791
2792 for (advance = 0, i = glyph_start; i < glyph_end; i++)
2793 advance += piAdvance[i];
2794
2795 return advance;
2796}
_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 2716 of file usp10.c.

2717{
2718 int size = 0;
2719 int i;
2720
2721 for (i = 0; i < cChars; i++)
2722 {
2723 if (pwLogClust[i] == cluster_index)
2724 {
2725 if (!size && start_index)
2726 {
2727 *start_index = i;
2728 if (!cluster_size)
2729 return TRUE;
2730 }
2731 size++;
2732 }
2733 else if (size) break;
2734 }
2735 if (cluster_size)
2736 *cluster_size = size;
2737
2738 return (size > 0);
2739}
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 2550 of file usp10.c.

2552{
2553 int clust_size = 1;
2554 int check;
2555 WORD clust = pwLogClust[item];
2556
2557 for (check = item+direction; check < cChars && check >= 0; check+=direction)
2558 {
2559 if (pwLogClust[check] == clust)
2560 {
2561 clust_size ++;
2562 if (iCluster && *iCluster == -1)
2563 *iCluster = item;
2564 }
2565 else break;
2566 }
2567
2568 if (check_out)
2569 *check_out = check;
2570
2571 return clust_size;
2572}
#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 2574 of file usp10.c.

2575{
2576 int advance;
2577 int log_clust_max;
2578
2579 advance = piAdvance[glyph];
2580
2581 if (pwLogClust[0] > pwLogClust[cChars-1])
2582 log_clust_max = pwLogClust[0];
2583 else
2584 log_clust_max = pwLogClust[cChars-1];
2585
2586 if (glyph > log_clust_max)
2587 return advance;
2588
2589 for (glyph+=direction; glyph < cGlyphs && glyph >= 0; glyph +=direction)
2590 {
2591
2592 if (does_glyph_start_cluster(pva, pwLogClust, cChars, glyph, direction))
2593 break;
2594 if (glyph > log_clust_max)
2595 break;
2596 advance += piAdvance[glyph];
2597 }
2598
2599 return advance;
2600}
static BOOL does_glyph_start_cluster(const SCRIPT_VISATTR *pva, const WORD *pwLogClust, int cChars, int glyph, int direction)
Definition: usp10.c:2146

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

◆ getGivenTabWidth()

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

Definition at line 1781 of file usp10.c.

1782{
1783 int defWidth;
1784 int cTabStops=0;
1785 INT *lpTabPos = NULL;
1786 INT nTabOrg = 0;
1787 INT x = 0;
1788
1789 if (pTabdef)
1790 lpTabPos = pTabdef->pTabStops;
1791
1792 if (pTabdef && pTabdef->iTabOrigin)
1793 {
1794 if (pTabdef->iScale)
1795 nTabOrg = (pTabdef->iTabOrigin * pTabdef->iScale)/4;
1796 else
1797 nTabOrg = pTabdef->iTabOrigin * psc->tm.tmAveCharWidth;
1798 }
1799
1800 if (pTabdef)
1801 cTabStops = pTabdef->cTabStops;
1802
1803 if (cTabStops == 1)
1804 {
1805 if (pTabdef->iScale)
1806 defWidth = ((pTabdef->pTabStops[0])*pTabdef->iScale) / 4;
1807 else
1808 defWidth = (pTabdef->pTabStops[0])*psc->tm.tmAveCharWidth;
1809 cTabStops = 0;
1810 }
1811 else
1812 {
1813 if (pTabdef->iScale)
1814 defWidth = (32 * pTabdef->iScale) / 4;
1815 else
1816 defWidth = 8 * psc->tm.tmAveCharWidth;
1817 }
1818
1819 for (; cTabStops>0 ; lpTabPos++, cTabStops--)
1820 {
1821 int position = *lpTabPos;
1822 if (position < 0)
1823 position = -1 * position;
1824 if (pTabdef->iScale)
1825 position = (position * pTabdef->iScale) / 4;
1826 else
1827 position = position * psc->tm.tmAveCharWidth;
1828
1829 if( nTabOrg + position > current_x)
1830 {
1831 if( position >= 0)
1832 {
1833 /* a left aligned tab */
1834 x = (nTabOrg + position) - current_x;
1835 break;
1836 }
1837 else
1838 {
1839 FIXME("Negative tabstop\n");
1840 break;
1841 }
1842 }
1843 }
1844 if ((!cTabStops) && (defWidth > 0))
1845 x =((((current_x - nTabOrg) / defWidth)+1) * defWidth) - current_x;
1846 else if ((!cTabStops) && (defWidth < 0))
1847 FIXME("TODO: Negative defWidth\n");
1848
1849 return x;
1850}
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 unsigned size;
793 LOGFONTW lf;
794
795 if (!psc) return E_INVALIDARG;
796 if (*psc) return S_OK;
797 if (!hdc) return E_PENDING;
798
799 if (!GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf))
800 {
801 return E_INVALIDARG;
802 }
803 /* Ensure canonical result by zeroing extra space in lfFaceName */
805 memset(lf.lfFaceName + size, 0, sizeof(lf.lfFaceName) - size * sizeof(WCHAR));
806
809 {
810 if (!memcmp(&sc->lf, &lf, sizeof(lf)))
811 {
812 sc->refcount++;
814 *psc = sc;
815 return S_OK;
816 }
817 }
819
820 if (!(sc = calloc(1, sizeof(ScriptCache)))) return E_OUTOFMEMORY;
821 if (!GetTextMetricsW(hdc, &sc->tm))
822 {
823 free(sc);
824 return E_INVALIDARG;
825 }
827 if (size)
828 {
829 sc->otm = malloc(size);
830 sc->otm->otmSize = size;
832 }
833 sc->sfnt = (NtGdiGetFontData(hdc, MS_MAKE_TAG('h','e','a','d'), 0, NULL, 0) != GDI_ERROR);
835 {
836 free(sc);
837 return E_INVALIDARG;
838 }
839 sc->lf = lf;
840 sc->refcount = 1;
841 *psc = sc;
842
846 {
847 if (sc != *psc && !memcmp(&sc->lf, &lf, sizeof(lf)))
848 {
849 /* Another thread won the race. Use their cache instead of ours */
850 list_remove(&sc->entry);
851 sc->refcount++;
853 free(*psc);
854 *psc = sc;
855 return S_OK;
856 }
857 }
859 TRACE("<- %p\n", sc);
860 return S_OK;
861}
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 1229 of file usp10.c.

1230{
1232}

Referenced by _ItemizeInternal().

◆ mirror_char()

static WCHAR mirror_char ( WCHAR  ch)
static

Definition at line 863 of file usp10.c.

864{
865 extern const WCHAR wine_mirror_map[];
867 return mirror ? mirror : ch;
868}
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 1855 of file usp10.c.

1857{
1858 /* FIXME: When to properly fallback is still a bit of a mystery */
1859 WORD *glyphs;
1860
1861 if (psa->fNoGlyphIndex)
1862 return FALSE;
1863
1864 if (init_script_cache(hdc, psc) != S_OK)
1865 return FALSE;
1866
1868 return TRUE;
1869
1870 if (!(glyphs = calloc(cChars, sizeof(*glyphs))))
1871 return FALSE;
1872 if (ScriptGetCMap(hdc, psc, pwcInChars, cChars, 0, glyphs) != S_OK)
1873 {
1874 free(glyphs);
1875 return TRUE;
1876 }
1877 free(glyphs);
1878
1879 return FALSE;
1880}
HRESULT WINAPI ScriptGetCMap(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcInChars, int cChars, DWORD dwFlags, WORD *pwOutGlyphs)
Definition: usp10.c:3515
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 1263 of file usp10.c.

1264{
1266}
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 1199 of file usp10.c.

1201{
1203
1204 TRACE("%p, %p, %p\n", sds, sc, ss);
1205
1206 if (!sc || !ss) return E_POINTER;
1207 if (!sds)
1208 {
1209 sds = &psds;
1211 return E_INVALIDARG;
1212 }
1213
1215 sc->fContextDigits = 0;
1216 ss->fDigitSubstitute = 0;
1217
1218 switch (sds->DigitSubstitute) {
1223 return S_OK;
1224 default:
1225 return E_INVALIDARG;
1226 }
1227}
HRESULT WINAPI ScriptRecordDigitSubstitution(LCID locale, SCRIPT_DIGITSUBSTITUTE *sds)
Definition: usp10.c:1133
#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 4012 of file usp10.c.

4016{
4017 int i;
4018
4019 FIXME("(%p, %d, %d, %p, %p, %p, %p, %p, %p)\n",
4020 dx, num_chars, num_glyphs, log_clust, sva, advance, sa, abc, justify);
4021
4022 for (i = 0; i < num_chars; i++) justify[i] = advance[i];
4023 return S_OK;
4024}
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 3003 of file usp10.c.

3004{
3005 TRACE("(%s, %d, %p, %p)\n", debugstr_wn(chars, count), count, sa, la);
3006
3007 if (count < 0 || !la) return E_INVALIDARG;
3008 if (count == 0) return E_FAIL;
3009
3010 BREAK_line(chars, count, sa, la);
3011
3012 return S_OK;
3013}
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 3643 of file usp10.c.

3644{
3645 HRESULT hr;
3646
3647 TRACE("(%p, %p, %p)\n", hdc, psc, height);
3648
3649 if (!height) return E_INVALIDARG;
3650 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3651
3652 *height = get_cache_height(psc);
3653 return S_OK;
3654}
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 2606 of file usp10.c.

2615{
2616 int item;
2617 float iPosX;
2618 int iSpecial = -1;
2619 int iCluster = -1;
2620 int clust_size = 1;
2621 float special_size = 0.0;
2622 int iMaxPos = 0;
2623 int advance = 0;
2624 BOOL rtl = FALSE;
2625
2626 TRACE("(%d,%d,%d,%d,%p,%p,%p,%p,%p)\n",
2627 iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance,
2628 psa, piX);
2629
2630 if (psa->fRTL && ! psa->fLogicalOrder)
2631 rtl = TRUE;
2632
2633 if (fTrailing)
2634 iCP++;
2635
2636 if (rtl)
2637 {
2638 int max_clust = pwLogClust[0];
2639
2640 for (item=0; item < cGlyphs; item++)
2641 if (pwLogClust[item] > max_clust)
2642 {
2643 ERR("We do not handle non reversed clusters properly\n");
2644 break;
2645 }
2646
2647 iMaxPos = 0;
2648 for (item = max_clust; item >=0; item --)
2649 iMaxPos += piAdvance[item];
2650 }
2651
2652 iPosX = 0.0;
2653 for (item=0; item < iCP && item < cChars; item++)
2654 {
2655 if (iSpecial == -1 && (iCluster == -1 || iCluster+clust_size <= item))
2656 {
2657 int check;
2658 int clust = pwLogClust[item];
2659
2660 iCluster = -1;
2661 clust_size = get_cluster_size(pwLogClust, cChars, item, 1, &iCluster,
2662 &check);
2663
2664 advance = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, clust, 1);
2665
2666 if (check >= cChars && !iMaxPos)
2667 {
2668 int glyph;
2669 for (glyph = clust; glyph < cGlyphs; glyph++)
2670 special_size += get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, glyph, 1);
2671 iSpecial = item;
2672 special_size /= (cChars - item);
2673 iPosX += special_size;
2674 }
2675 else
2676 {
2678 {
2679 clust_size --;
2680 if (clust_size == 0)
2681 iPosX += advance;
2682 }
2683 else
2684 iPosX += advance / (float)clust_size;
2685 }
2686 }
2687 else if (iSpecial != -1)
2688 iPosX += special_size;
2689 else /* (iCluster != -1) */
2690 {
2691 int adv = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, pwLogClust[iCluster], 1);
2693 {
2694 clust_size --;
2695 if (clust_size == 0)
2696 iPosX += adv;
2697 }
2698 else
2699 iPosX += adv / (float)clust_size;
2700 }
2701 }
2702
2703 if (iMaxPos > 0)
2704 {
2705 iPosX = iMaxPos - iPosX;
2706 if (iPosX < 0)
2707 iPosX = 0;
2708 }
2709
2710 *piX = iPosX;
2711 TRACE("*piX=%d\n", *piX);
2712 return S_OK;
2713}
#define ERR(fmt,...)
Definition: precomp.h:57
static int get_cluster_size(const WORD *pwLogClust, int cChars, int item, int direction, int *iCluster, int *check_out)
Definition: usp10.c:2550
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:2574
static BOOL rtl
Definition: propsheet.c:36
static float(__cdecl *square_half_float)(float x
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 1003 of file usp10.c.

1004{
1005 TRACE("%p\n", psc);
1006
1007 if (psc && *psc)
1008 {
1009 ScriptCache *sc = *psc;
1010 unsigned int i;
1011 INT n;
1012
1014 if (--sc->refcount > 0)
1015 {
1017 *psc = NULL;
1018 return S_OK;
1019 }
1020 list_remove(&sc->entry);
1022
1023 for (i = 0; i < GLYPH_MAX / GLYPH_BLOCK_SIZE; i++)
1024 {
1025 free(sc->widths[i]);
1026 }
1027 for (i = 0; i < NUM_PAGES; i++)
1028 {
1029 unsigned int j;
1030 if (sc->page[i])
1031 for (j = 0; j < GLYPH_MAX / GLYPH_BLOCK_SIZE; j++)
1032 free(sc->page[i]->glyphs[j]);
1033 free(sc->page[i]);
1034 }
1035 free(sc->GSUB_Table);
1036 free(sc->GDEF_Table);
1037 free(sc->CMAP_Table);
1038 free(sc->GPOS_Table);
1039 for (n = 0; n < sc->script_count; n++)
1040 {
1041 int j;
1042 for (j = 0; j < sc->scripts[n].language_count; j++)
1043 {
1044 int k;
1045 for (k = 0; k < sc->scripts[n].languages[j].feature_count; k++)
1048 }
1049 for (j = 0; j < sc->scripts[n].default_language.feature_count; j++)
1052 free(sc->scripts[n].languages);
1053 }
1054 free(sc->scripts);
1055 free(sc->otm);
1056 free(sc);
1057 *psc = NULL;
1058 }
1059 return S_OK;
1060}
#define GLYPH_BLOCK_SIZE
#define GLYPH_MAX
GLdouble n
Definition: glext.h:7729
int k
Definition: mpi.c:3369
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 3515 of file usp10.c.

3517{
3518 HRESULT hr;
3519 int i;
3520
3521 TRACE("(%p,%p,%s,%d,0x%lx,%p)\n", hdc, psc, debugstr_wn(pwcInChars, cChars),
3522 cChars, dwFlags, pwOutGlyphs);
3523
3524 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3525
3526 hr = S_OK;
3527
3528 for (i = 0; i < cChars; i++)
3529 {
3530 WCHAR inChar;
3531 if (dwFlags == SGCM_RTL)
3532 inChar = mirror_char(pwcInChars[i]);
3533 else
3534 inChar = pwcInChars[i];
3535 if (!(pwOutGlyphs[i] = get_cache_glyph(psc, inChar)))
3536 {
3537 WORD glyph;
3538 if (!hdc) return E_PENDING;
3540 return S_FALSE;
3541 if (glyph == 0xffff)
3542 {
3543 hr = S_FALSE;
3544 glyph = 0x0;
3545 }
3546 pwOutGlyphs[i] = set_cache_glyph(psc, inChar, glyph);
3547 }
3548 }
3549
3550 return hr;
3551}
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:863
_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 4064 of file usp10.c.

4066{
4067 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),
4068 debugstr_an((char*)&tag_feature,4), id, size, list, count);
4069
4070 if(count)
4071 *count = 0;
4072
4073 return E_NOTIMPL;
4074}
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 4055 of file usp10.c.

4056{
4057 HRESULT hr;
4058 if (!pFeatureTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4059 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4060
4061 return SHAPE_GetFontFeatureTags(hdc, (ScriptCache *)*psc, psa, tagScript, tagLangSys, cMaxTags, pFeatureTags, pcTags);
4062}
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 4046 of file usp10.c.

4047{
4048 HRESULT hr;
4049 if (!pLangSysTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4050 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4051
4052 return SHAPE_GetFontLanguageTags(hdc, (ScriptCache *)*psc, psa, tagScript, cMaxTags, pLangSysTags, pcTags);
4053}
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 1100 of file usp10.c.

1101{
1102 HRESULT hr;
1103
1104 TRACE("%p,%p,%p\n", hdc, psc, sfp);
1105
1106 if (!sfp) return E_INVALIDARG;
1107 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
1108
1109 if (sfp->cBytes != sizeof(SCRIPT_FONTPROPERTIES))
1110 return E_INVALIDARG;
1111
1112 get_cache_font_properties(sfp, *psc);
1113
1114 return S_OK;
1115}
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 4037 of file usp10.c.

4038{
4039 HRESULT hr;
4040 if (!pScriptTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4041 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4042
4043 return SHAPE_GetFontScriptTags(hdc, (ScriptCache *)*psc, psa, cMaxTags, pScriptTags, pcTags);
4044}
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 3671 of file usp10.c.

3672{
3673 HRESULT hr;
3674
3675 TRACE("(%p, %p, 0x%04x, %p)\n", hdc, psc, glyph, abc);
3676
3677 if (!abc) return E_INVALIDARG;
3678 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3679
3680 if (!get_cache_glyph_widths(psc, glyph, abc))
3681 {
3682 if (!hdc) return E_PENDING;
3684 {
3685 if (!GetCharABCWidthsI(hdc, 0, 1, &glyph, abc)) return S_FALSE;
3686 }
3687 else
3688 {
3689 INT width;
3690 if (!GetCharWidthI(hdc, glyph, 1, NULL, &width)) return S_FALSE;
3691 abc->abcB = width;
3692 abc->abcA = abc->abcC = 0;
3693 }
3694 set_cache_glyph_widths(psc, glyph, abc);
3695 }
3696 return S_OK;
3697}
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 3961 of file usp10.c.

3964{
3965 int i, next = 0, direction;
3966
3967 TRACE("(%p, %d, %d, %p, %p, %p, %p)\n",
3968 sa, nbchars, nbglyphs, advances, log_clust, sva, widths);
3969
3970 if (sa->fRTL && !sa->fLogicalOrder)
3971 direction = -1;
3972 else
3973 direction = 1;
3974
3975 for (i = 0; i < nbchars; i++)
3976 {
3977 int clust_size = get_cluster_size(log_clust, nbchars, i, direction, NULL, NULL);
3978 int advance = get_glyph_cluster_advance(advances, sva, log_clust, nbglyphs, nbchars, log_clust[i], direction);
3979 int j;
3980
3981 for (j = 0; j < clust_size; j++)
3982 {
3983 widths[next] = advance / clust_size;
3984 next++;
3985 if (j) i++;
3986 }
3987 }
3988
3989 return S_OK;
3990}
static unsigned __int64 next
Definition: rand_nt.c:6

Referenced by test_ScriptGetLogicalWidths().

◆ ScriptGetProperties()

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

Definition at line 1078 of file usp10.c.

1079{
1080 TRACE("(%p,%p)\n", props, num);
1081
1082 if (!props && !num) return E_INVALIDARG;
1083
1084 if (num) *num = ARRAY_SIZE(script_props);
1085 if (props) *props = script_props;
1086
1087 return S_OK;
1088}
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 3030 of file usp10.c.

3031{
3032 enum usp10_script script;
3033 unsigned int i, consumed;
3034
3035 TRACE("(%s,%d,0x%lx)\n", debugstr_wn(chars, len), len, flag);
3036
3037 if (!chars || len < 0)
3038 return E_INVALIDARG;
3039
3040 for (i = 0; i < len; i+=consumed)
3041 {
3042 if ((flag & SIC_ASCIIDIGIT) && chars[i] >= 0x30 && chars[i] <= 0x39)
3043 return S_OK;
3044
3045 script = get_char_script(chars,i,len, &consumed);
3046 if ((scriptInformation[script].props.fComplex && (flag & SIC_COMPLEX))||
3048 return S_OK;
3049 }
3050 return S_FALSE;
3051}
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 1774 of file usp10.c.

1777{
1778 return _ItemizeInternal(pwcInChars, cInChars, cMaxItems, psControl, psState, pItems, NULL, pcItems);
1779}
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:1268

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 1749 of file usp10.c.

1752{
1753 return _ItemizeInternal(pwcInChars, cInChars, cMaxItems, psControl, psState, pItems, pScriptTags, pcItems);
1754}

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 4026 of file usp10.c.

4028{
4029 int i;
4030
4031 FIXME("(%p, %p, %d, %d, %d, %p)\n", sva, advance, num_glyphs, dx, min_kashida, justify);
4032
4033 for (i = 0; i < num_glyphs; i++) justify[i] = advance[i];
4034 return S_OK;
4035}

◆ ScriptLayout()

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

Definition at line 3715 of file usp10.c.

3716{
3717 int* indices;
3718 int ich;
3719
3720 TRACE("(%d, %p, %p, %p)\n", runs, level, vistolog, logtovis);
3721
3722 if (!level || (!vistolog && !logtovis))
3723 return E_INVALIDARG;
3724
3725 if (!(indices = calloc(runs, sizeof(*indices))))
3726 return E_OUTOFMEMORY;
3727
3728 if (vistolog)
3729 {
3730 for( ich = 0; ich < runs; ich++)
3731 indices[ich] = ich;
3732
3733 ich = 0;
3734 while (ich < runs)
3735 ich += BIDI_ReorderV2lLevel(0, indices+ich, level+ich, runs - ich, FALSE);
3736 memcpy(vistolog, indices, runs * sizeof(*vistolog));
3737 }
3738
3739 if (logtovis)
3740 {
3741 for( ich = 0; ich < runs; ich++)
3742 indices[ich] = ich;
3743
3744 ich = 0;
3745 while (ich < runs)
3746 ich += BIDI_ReorderL2vLevel(0, indices+ich, level+ich, runs - ich, FALSE);
3747 memcpy(logtovis, indices, runs * sizeof(*logtovis));
3748 }
3749 free(indices);
3750
3751 return S_OK;
3752}
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 3471 of file usp10.c.

3474{
3475 HRESULT hr;
3476 SCRIPT_GLYPHPROP *glyphProps;
3477 int i;
3478
3479 TRACE("(%p, %p, %p, %d, %p, %p, %p, %p, %p)\n", hdc, psc, pwGlyphs, cGlyphs, psva, psa,
3480 piAdvance, pGoffset, pABC);
3481
3482 if (!psva) return E_INVALIDARG;
3483 if (!pGoffset) return E_FAIL;
3484
3485 if (!(glyphProps = calloc(cGlyphs, sizeof(*glyphProps))))
3486 return E_OUTOFMEMORY;
3487
3488 for (i = 0; i < cGlyphs; i++)
3489 glyphProps[i].sva = psva[i];
3490
3491 hr = ScriptPlaceOpenType(hdc, psc, psa, scriptInformation[psa->eScript].scriptTag, 0, NULL, NULL, 0, NULL, NULL, NULL, 0, pwGlyphs, glyphProps, cGlyphs, piAdvance, pGoffset, pABC);
3492
3493 free(glyphProps);
3494
3495 return hr;
3496}
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:3348

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 3348 of file usp10.c.

3357{
3358 HRESULT hr;
3359 int i;
3360 static int once = 0;
3361
3362 TRACE("(%p, %p, %p, %s, %s, %p, %p, %d, %s, %p, %p, %d, %p, %p, %d, %p %p %p)\n",
3363 hdc, psc, psa,
3364 debugstr_an((char*)&tagScript,4), debugstr_an((char*)&tagLangSys,4),
3365 rcRangeChars, rpRangeProperties, cRanges, debugstr_wn(pwcChars, cChars),
3366 pwLogClust, pCharProps, cChars, pwGlyphs, pGlyphProps, cGlyphs, piAdvance,
3367 pGoffset, pABC);
3368
3369 if (!pGlyphProps) return E_INVALIDARG;
3370 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3371 if (!pGoffset) return E_FAIL;
3372
3373 if (cRanges)
3374 if (!once++) FIXME("Ranges not supported yet\n");
3375
3376 ((ScriptCache *)*psc)->userScript = tagScript;
3377 ((ScriptCache *)*psc)->userLang = tagLangSys;
3378
3379 if (pABC) memset(pABC, 0, sizeof(ABC));
3380 for (i = 0; i < cGlyphs; i++)
3381 {
3382 WORD glyph;
3383 ABC abc;
3384
3385 /* FIXME: set to more reasonable values */
3386 pGoffset[i].du = pGoffset[i].dv = 0;
3387
3388 if (pGlyphProps[i].sva.fZeroWidth)
3389 {
3390 abc.abcA = abc.abcB = abc.abcC = 0;
3391 if (piAdvance) piAdvance[i] = 0;
3392 continue;
3393 }
3394
3395 if (psa->fNoGlyphIndex)
3396 {
3397 if (FAILED(hr = ScriptGetCMap(hdc, psc, &pwGlyphs[i], 1, 0, &glyph))) return hr;
3398 }
3399 else
3400 {
3401 hr = S_OK;
3402 glyph = pwGlyphs[i];
3403 }
3404
3405 if (hr == S_FALSE)
3406 {
3407 if (!hdc) return E_PENDING;
3409 {
3410 if (!GetCharABCWidthsW(hdc, pwGlyphs[i], pwGlyphs[i], &abc)) return S_FALSE;
3411 }
3412 else
3413 {
3414 INT width;
3415 if (!GetCharWidth32W(hdc, pwGlyphs[i], pwGlyphs[i], &width)) return S_FALSE;
3416 abc.abcB = width;
3417 abc.abcA = abc.abcC = 0;
3418 }
3419 }
3420 else if (!get_cache_glyph_widths(psc, glyph, &abc))
3421 {
3422 if (!hdc) return E_PENDING;
3424 {
3425 if (!GetCharABCWidthsI(hdc, glyph, 1, NULL, &abc)) return S_FALSE;
3426 }
3427 else
3428 {
3429 INT width;
3430 if (!GetCharWidthI(hdc, glyph, 1, NULL, &width)) return S_FALSE;
3431 abc.abcB = width;
3432 abc.abcA = abc.abcC = 0;
3433 }
3434 set_cache_glyph_widths(psc, glyph, &abc);
3435 }
3436 if (pABC)
3437 {
3438 pABC->abcA += abc.abcA;
3439 pABC->abcB += abc.abcB;
3440 pABC->abcC += abc.abcC;
3441 }
3442 if (piAdvance) piAdvance[i] = abc.abcA + abc.abcB + abc.abcC;
3443 }
3444
3445 SHAPE_ApplyOpenTypePositions(hdc, (ScriptCache *)*psc, psa, pwGlyphs, cGlyphs, piAdvance, pGoffset);
3446
3447 if (pABC) TRACE("Total for run: abcA=%d, abcB=%d, abcC=%d\n", pABC->abcA, pABC->abcB, pABC->abcC);
3448 return S_OK;
3449}
#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 1133 of file usp10.c.

1134{
1135 DWORD plgid, sub;
1136
1137 TRACE("0x%lx, %p\n", locale, sds);
1138
1139 /* This implementation appears to be correct for all languages, but it's
1140 * not clear if sds->DigitSubstitute is ever set to anything except
1141 * CONTEXT or NONE in reality */
1142
1143 if (!sds) return E_POINTER;
1144
1146
1148 return E_INVALIDARG;
1149
1151 sds->TraditionalDigitLanguage = plgid;
1152
1153 if (plgid == LANG_ARABIC || plgid == LANG_FARSI)
1154 sds->NationalDigitLanguage = plgid;
1155 else
1157
1158 if (!GetLocaleInfoW(locale, LOCALE_IDIGITSUBSTITUTION | LOCALE_RETURN_NUMBER,
1159 (WCHAR *)&sub, sizeof(sub) / sizeof(WCHAR)))
1160 return E_INVALIDARG;
1161
1162 switch (sub)
1163 {
1164 case 0:
1165 if (plgid == LANG_ARABIC || plgid == LANG_FARSI)
1167 else
1169 break;
1170 case 1:
1172 break;
1173 case 2:
1175 break;
1176 default:
1178 break;
1179 }
1180
1181 sds->dwReserved = 0;
1182 return S_OK;
1183}
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 3282 of file usp10.c.

3286{
3287 HRESULT hr;
3288 int i;
3289 SCRIPT_CHARPROP *charProps;
3290 SCRIPT_GLYPHPROP *glyphProps;
3291
3292 if (!psva || !pcGlyphs) return E_INVALIDARG;
3293 if (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
3294
3295 if (!(charProps = calloc(cChars, sizeof(*charProps))))
3296 return E_OUTOFMEMORY;
3297
3298 if (!(glyphProps = calloc(cMaxGlyphs, sizeof(*glyphProps))))
3299 {
3300 free(charProps);
3301 return E_OUTOFMEMORY;
3302 }
3303
3304 hr = ScriptShapeOpenType(hdc, psc, psa, scriptInformation[psa->eScript].scriptTag, 0, NULL, NULL, 0, pwcChars, cChars, cMaxGlyphs, pwLogClust, charProps, pwOutGlyphs, glyphProps, pcGlyphs);
3305
3306 if (SUCCEEDED(hr))
3307 {
3308 for (i = 0; i < *pcGlyphs; i++)
3309 psva[i] = glyphProps[i].sva;
3310 }
3311
3312 free(charProps);
3313 free(glyphProps);
3314
3315 return hr;
3316}
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:3080
#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 3080 of file usp10.c.

3088{
3089 HRESULT hr;
3090 int i;
3091 unsigned int g;
3092 BOOL rtl;
3093 int cluster;
3094 static int once = 0;
3095
3096 TRACE("(%p, %p, %p, %s, %s, %p, %p, %d, %s, %d, %d, %p, %p, %p, %p, %p )\n",
3097 hdc, psc, psa,
3098 debugstr_an((char*)&tagScript,4), debugstr_an((char*)&tagLangSys,4),
3099 rcRangeChars, rpRangeProperties, cRanges, debugstr_wn(pwcChars, cChars),
3100 cChars, cMaxGlyphs, pwLogClust, pCharProps, pwOutGlyphs, pOutGlyphProps, pcGlyphs);
3101
3102 if (psa) TRACE("psa values: %d, %d, %d, %d, %d, %d, %d\n", psa->eScript, psa->fRTL, psa->fLayoutRTL,
3103 psa->fLinkBefore, psa->fLinkAfter, psa->fLogicalOrder, psa->fNoGlyphIndex);
3104
3105 if (!pOutGlyphProps || !pcGlyphs || !pCharProps) return E_INVALIDARG;
3106 if (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
3107
3108 if (cRanges)
3109 if(!once++) FIXME("Ranges not supported yet\n");
3110
3111 rtl = (psa && !psa->fLogicalOrder && psa->fRTL);
3112
3113 *pcGlyphs = cChars;
3114 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3115 if (!pwLogClust) return E_FAIL;
3116
3117 ((ScriptCache *)*psc)->userScript = tagScript;
3118 ((ScriptCache *)*psc)->userLang = tagLangSys;
3119
3120 /* Initialize a SCRIPT_VISATTR and LogClust for each char in this run */
3121 for (i = 0; i < cChars; i++)
3122 {
3123 int idx = i;
3124 if (rtl) idx = cChars - 1 - i;
3125 /* FIXME: set to better values */
3126 pOutGlyphProps[i].sva.uJustification = (pwcChars[idx] == ' ') ? SCRIPT_JUSTIFY_BLANK : SCRIPT_JUSTIFY_CHARACTER;
3127 pOutGlyphProps[i].sva.fClusterStart = 1;
3128 pOutGlyphProps[i].sva.fDiacritic = 0;
3129 pOutGlyphProps[i].sva.fZeroWidth = 0;
3130 pOutGlyphProps[i].sva.fReserved = 0;
3131 pOutGlyphProps[i].sva.fShapeReserved = 0;
3132
3133 /* FIXME: have the shaping engine set this */
3134 pCharProps[i].fCanGlyphAlone = 0;
3135
3136 pwLogClust[i] = idx;
3137 }
3138
3139 if (psa && !psa->fNoGlyphIndex && ((ScriptCache *)*psc)->sfnt)
3140 {
3141 WCHAR *rChars;
3142 if ((hr = SHAPE_CheckFontForRequiredFeatures(hdc, (ScriptCache *)*psc, psa)) != S_OK) return hr;
3143
3144 if (!(rChars = calloc(cChars, sizeof(*rChars))))
3145 return E_OUTOFMEMORY;
3146
3147 for (i = 0, g = 0, cluster = 0; i < cChars; i++)
3148 {
3149 int idx = i;
3150 DWORD chInput;
3151
3152 if (rtl) idx = cChars - 1 - i;
3153 if (!cluster)
3154 {
3155 chInput = decode_surrogate_pair(pwcChars, idx, cChars);
3156 if (!chInput)
3157 {
3158 if (psa->fRTL)
3159 chInput = mirror_char(pwcChars[idx]);
3160 else
3161 chInput = pwcChars[idx];
3162 rChars[i] = chInput;
3163 }
3164 else
3165 {
3166 rChars[i] = pwcChars[idx];
3167 rChars[i+1] = pwcChars[(rtl)?idx-1:idx+1];
3168 cluster = 1;
3169 }
3170 if (!(pwOutGlyphs[g] = get_cache_glyph(psc, chInput)))
3171 {
3172 WORD glyph;
3173 if (!hdc)
3174 {
3175 free(rChars);
3176 return E_PENDING;
3177 }
3178 if (OpenType_CMAP_GetGlyphIndex(hdc, (ScriptCache *)*psc, chInput, &glyph, 0) == GDI_ERROR)
3179 {
3180 free(rChars);
3181 return S_FALSE;
3182 }
3183 pwOutGlyphs[g] = set_cache_glyph(psc, chInput, glyph);
3184 }
3185 g++;
3186 }
3187 else
3188 {
3189 int k;
3190 cluster--;
3191 pwLogClust[idx] = (rtl)?pwLogClust[idx+1]:pwLogClust[idx-1];
3192 for (k = (rtl)?idx-1:idx+1; k >= 0 && k < cChars; (rtl)?k--:k++)
3193 pwLogClust[k]--;
3194 }
3195 }
3196 *pcGlyphs = g;
3197
3198 hr = SHAPE_ContextualShaping(hdc, (ScriptCache *)*psc, psa, rChars, cChars, pwOutGlyphs, pcGlyphs, cMaxGlyphs, pwLogClust);
3199 if (FAILED(hr))
3200 {
3201 free(rChars);
3202 return hr;
3203 }
3204 SHAPE_ApplyDefaultOpentypeFeatures(hdc, (ScriptCache *)*psc, psa, pwOutGlyphs, pcGlyphs, cMaxGlyphs, cChars, pwLogClust);
3205 SHAPE_CharGlyphProp(hdc, (ScriptCache *)*psc, psa, pwcChars, cChars, pwOutGlyphs, *pcGlyphs, pwLogClust, pCharProps, pOutGlyphProps);
3206
3207 for (i = 0; i < cChars; ++i)
3208 {
3209 /* Special case for tabs and joiners. As control characters, ZWNJ
3210 * and ZWJ would in principle get handled by the corresponding
3211 * shaping functions. However, since ZWNJ and ZWJ can get merged
3212 * into adjoining runs during itemisation, these don't generally
3213 * get classified as Script_Control. */
3214 if (pwcChars[i] == 0x0009 || pwcChars[i] == ZWSP || pwcChars[i] == ZWNJ || pwcChars[i] == ZWJ)
3215 {
3216 pwOutGlyphs[pwLogClust[i]] = ((ScriptCache *)*psc)->sfp.wgBlank;
3217 pOutGlyphProps[pwLogClust[i]].sva.fZeroWidth = 1;
3218 }
3219 }
3220 free(rChars);
3221 }
3222 else
3223 {
3224 TRACE("no glyph translation\n");
3225 for (i = 0; i < cChars; i++)
3226 {
3227 int idx = i;
3228 /* No mirroring done here */
3229 if (rtl) idx = cChars - 1 - i;
3230 pwOutGlyphs[i] = pwcChars[idx];
3231
3232 if (!psa)
3233 continue;
3234
3235 /* overwrite some basic control glyphs to blank */
3236 if (psa->fNoGlyphIndex)
3237 {
3238 if (pwcChars[idx] == ZWSP || pwcChars[idx] == ZWNJ || pwcChars[idx] == ZWJ)
3239 {
3240 pwOutGlyphs[i] = 0x20;
3241 pOutGlyphProps[i].sva.fZeroWidth = 1;
3242 }
3243 }
3244 else if (psa->eScript == Script_Control || pwcChars[idx] == ZWSP
3245 || pwcChars[idx] == ZWNJ || pwcChars[idx] == ZWJ)
3246 {
3247 if (pwcChars[idx] == 0x0009 || pwcChars[idx] == 0x000A ||
3248 pwcChars[idx] == 0x000D || pwcChars[idx] >= 0x001C)
3249 {
3250 pwOutGlyphs[i] = ((ScriptCache *)*psc)->sfp.wgBlank;
3251 pOutGlyphProps[i].sva.fZeroWidth = 1;
3252 }
3253 }
3254 }
3255 }
3256
3257 return S_OK;
3258}
@ 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 3901 of file usp10.c.

3902{
3903 StringAnalysis *analysis = ssa;
3904
3905 TRACE("(%p)\n", ssa);
3906
3907 if (!analysis) return NULL;
3908 return &analysis->clip_len;
3909}
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 3878 of file usp10.c.

3879{
3880 StringAnalysis *analysis = ssa;
3881
3882 TRACE("(%p)\n", ssa);
3883
3884 if (!analysis) return NULL;
3885 if (!(analysis->ssa_flags & SSA_BREAK)) return NULL;
3886 return analysis->logattrs;
3887}
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 3839 of file usp10.c.

3840{
3841 int i, j;
3842 StringAnalysis *analysis = ssa;
3843
3844 TRACE("(%p)\n", ssa);
3845
3846 if (!analysis) return NULL;
3847 if (!(analysis->ssa_flags & SSA_GLYPHS)) return NULL;
3848
3849 if (!(analysis->flags & SCRIPT_STRING_ANALYSIS_FLAGS_SIZE))
3850 {
3851 analysis->sz.cy = analysis->glyphs[0].sc->tm.tmHeight;
3852
3853 analysis->sz.cx = 0;
3854 for (i = 0; i < analysis->numItems; i++)
3855 {
3856 if (analysis->glyphs[i].sc->tm.tmHeight > analysis->sz.cy)
3857 analysis->sz.cy = analysis->glyphs[i].sc->tm.tmHeight;
3858 for (j = 0; j < analysis->glyphs[i].numGlyphs; j++)
3859 analysis->sz.cx += analysis->glyphs[i].piAdvance[j];
3860 }
3862 }
3863 return &analysis->sz;
3864}
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 1905 of file usp10.c.

1911{
1913 StringAnalysis *analysis = NULL;
1914 SCRIPT_CONTROL sControl;
1915 SCRIPT_STATE sState;
1916 int i, num_items = cString + 1;
1917 BYTE *BidiLevel = NULL;
1918 WCHAR *iString = NULL;
1920
1921 TRACE("(%p,%p,%d,%d,%d,0x%lx,%d,%p,%p,%p,%p,%p,%p)\n",
1922 hdc, pString, cString, cGlyphs, iCharset, dwFlags, iReqWidth,
1923 psControl, psState, piDx, pTabdef, pbInClass, pssa);
1924
1925 if (iCharset != -1)
1926 {
1927 FIXME("Only Unicode strings are supported\n");
1928 return E_INVALIDARG;
1929 }
1930 if (cString < 1 || !pString) return E_INVALIDARG;
1931 if ((dwFlags & SSA_GLYPHS) && !hdc) return E_PENDING;
1932
1933 if (!(analysis = calloc(1, sizeof(*analysis))))
1934 return E_OUTOFMEMORY;
1935 if (!(analysis->pItem = calloc(num_items, sizeof(*analysis->pItem))))
1936 goto error;
1937
1938 /* FIXME: handle clipping */
1939 analysis->clip_len = cString;
1940 analysis->hdc = hdc;
1941 analysis->ssa_flags = dwFlags;
1942
1943 if (psState)
1944 sState = *psState;
1945 else
1946 memset(&sState, 0, sizeof(SCRIPT_STATE));
1947
1948 if (psControl)
1949 sControl = *psControl;
1950 else
1951 memset(&sControl, 0, sizeof(SCRIPT_CONTROL));
1952
1953 if (dwFlags & SSA_PASSWORD)
1954 {
1955 if (!(iString = calloc(cString, sizeof(*iString))))
1956 {
1957 hr = E_OUTOFMEMORY;
1958 goto error;
1959 }
1960 for (i = 0; i < cString; i++)
1961 iString[i] = *((const WCHAR *)pString);
1962 pString = iString;
1963 }
1964
1965 hr = ScriptItemize(pString, cString, num_items, &sControl, &sState, analysis->pItem,
1966 &analysis->numItems);
1967 if (FAILED(hr))
1968 goto error;
1969
1970 /* Having as many items as codepoints is the worst case scenario, try to reclaim some memory. */
1971 if ((items = realloc(analysis->pItem, (analysis->numItems + 1) * sizeof(*analysis->pItem))))
1972 analysis->pItem = items;
1973
1974 /* set back to out of memory for default goto error behaviour */
1975 hr = E_OUTOFMEMORY;
1976
1977 if (dwFlags & SSA_BREAK)
1978 {
1979 if (!(analysis->logattrs = calloc(cString, sizeof(*analysis->logattrs))))
1980 goto error;
1981
1982 for (i = 0; i < analysis->numItems; ++i)
1983 ScriptBreak(&((const WCHAR *)pString)[analysis->pItem[i].iCharPos],
1984 analysis->pItem[i + 1].iCharPos - analysis->pItem[i].iCharPos,
1985 &analysis->pItem[i].a, &analysis->logattrs[analysis->pItem[i].iCharPos]);
1986 }
1987
1988 if (!(analysis->logical2visual = calloc(analysis->numItems, sizeof(*analysis->logical2visual))))
1989 goto error;
1990 if (!(BidiLevel = calloc(analysis->numItems, sizeof(*BidiLevel))))
1991 goto error;
1992
1993 if (dwFlags & SSA_GLYPHS)
1994 {
1995 int tab_x = 0;
1996
1997 if (!(analysis->glyphs = calloc(analysis->numItems, sizeof(*analysis->glyphs))))
1998 goto error;
1999
2000 for (i = 0; i < analysis->numItems; i++)
2001 {
2002 SCRIPT_CACHE *sc = (SCRIPT_CACHE*)&analysis->glyphs[i].sc;
2003 int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
2004 int multiplier = 2;
2005 int numGlyphs;
2006 WORD *glyphs = NULL;
2007 WORD *pwLogClust = calloc(cChar, sizeof(*pwLogClust));
2008 int *piAdvance = NULL;
2009 SCRIPT_VISATTR *psva = NULL;
2010 GOFFSET *pGoffset = NULL;
2011 int numGlyphsReturned;
2012 HFONT originalFont = 0x0;
2013
2014 /* FIXME: non unicode strings */
2015 const WCHAR* pStr = (const WCHAR*)pString;
2016 analysis->glyphs[i].fallbackFont = NULL;
2017
2018 if (!pwLogClust)
2019 {
2020 hr = E_OUTOFMEMORY;
2021 goto error;
2022 }
2023
2024 if ((dwFlags & SSA_FALLBACK) && requires_fallback(hdc, sc, &analysis->pItem[i].a, &pStr[analysis->pItem[i].iCharPos], cChar))
2025 {
2026 LOGFONTW lf;
2027 GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), & lf);
2029 lf.lfFaceName[0] = 0;
2030 find_fallback_font(analysis->pItem[i].a.eScript, lf.lfFaceName);
2031 if (lf.lfFaceName[0])
2032 {
2033 analysis->glyphs[i].fallbackFont = CreateFontIndirectW(&lf);
2034 if (analysis->glyphs[i].fallbackFont)
2035 {
2036 ScriptFreeCache(sc);
2037 originalFont = SelectObject(hdc, analysis->glyphs[i].fallbackFont);
2038 }
2039 }
2040 }
2041
2042 /* FIXME: When we properly shape Hangul remove this check */
2043 if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && analysis->pItem[i].a.eScript == Script_Hangul)
2044 analysis->pItem[i].a.fNoGlyphIndex = TRUE;
2045
2046 if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && !scriptInformation[analysis->pItem[i].a.eScript].props.fComplex && !analysis->pItem[i].a.fRTL)
2047 analysis->pItem[i].a.fNoGlyphIndex = TRUE;
2048
2049 while (TRUE)
2050 {
2051 if (multiplier > 8)
2052 {
2053 hr = E_OUTOFMEMORY;
2054 break;
2055 }
2056
2057 free(glyphs);
2058 free(piAdvance);
2059 free(psva);
2060 free(pGoffset);
2061
2062 numGlyphs = multiplier * cChar + 16;
2063 glyphs = calloc(numGlyphs, sizeof(*glyphs));
2064 piAdvance = calloc(numGlyphs, sizeof(*piAdvance));
2065 psva = calloc(numGlyphs, sizeof(*psva));
2066 pGoffset = calloc(numGlyphs, sizeof(*pGoffset));
2067
2068 if (!glyphs || !piAdvance || !psva || !pGoffset)
2069 {
2070 hr = E_OUTOFMEMORY;
2071 break;
2072 }
2073
2074 hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos], cChar, numGlyphs,
2075 &analysis->pItem[i].a, glyphs, pwLogClust, psva, &numGlyphsReturned);
2076 if (hr == E_OUTOFMEMORY)
2077 {
2078 multiplier *= 2;
2079 continue;
2080 }
2081
2082 hr = ScriptPlace(hdc, sc, glyphs, numGlyphsReturned, psva, &analysis->pItem[i].a,
2083 piAdvance, pGoffset, &analysis->glyphs[i].abc);
2084 break;
2085 }
2086
2087 if (originalFont)
2088 SelectObject(hdc,originalFont);
2089
2090 if (FAILED(hr))
2091 {
2092 free(glyphs);
2093 free(pwLogClust);
2094 free(piAdvance);
2095 free(psva);
2096 free(pGoffset);
2097 goto error;
2098 }
2099
2100 if (dwFlags & SSA_TAB)
2101 {
2102 int tabi = 0;
2103 for (tabi = 0; tabi < cChar; tabi++)
2104 {
2105 if (pStr[analysis->pItem[i].iCharPos+tabi] == 0x0009)
2106 piAdvance[tabi] = getGivenTabWidth(analysis->glyphs[i].sc, pTabdef, analysis->pItem[i].iCharPos+tabi, tab_x);
2107 tab_x+=piAdvance[tabi];
2108 }
2109 }
2110
2111 analysis->glyphs[i].numGlyphs = numGlyphsReturned;
2112 analysis->glyphs[i].glyphs = glyphs;
2113 analysis->glyphs[i].pwLogClust = pwLogClust;
2114 analysis->glyphs[i].piAdvance = piAdvance;
2115 analysis->glyphs[i].psva = psva;
2116 analysis->glyphs[i].pGoffset = pGoffset;
2117 analysis->glyphs[i].iMaxPosX= -1;
2118
2119 BidiLevel[i] = analysis->pItem[i].a.s.uBidiLevel;
2120 }
2121 }
2122 else
2123 {
2124 for (i = 0; i < analysis->numItems; i++)
2125 BidiLevel[i] = analysis->pItem[i].a.s.uBidiLevel;
2126 }
2127
2128 ScriptLayout(analysis->numItems, BidiLevel, NULL, analysis->logical2visual);
2129 free(BidiLevel);
2130
2131 *pssa = analysis;
2132 free(iString);
2133 return S_OK;
2134
2135error:
2136 free(iString);
2137 free(BidiLevel);
2138 free(analysis->glyphs);
2139 free(analysis->logattrs);
2140 free(analysis->pItem);
2141 free(analysis->logical2visual);
2142 free(analysis);
2143 return hr;
2144}
#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:3471
static int getGivenTabWidth(ScriptCache *psc, SCRIPT_TABDEF *pTabdef, int charPos, int current_x)
Definition: usp10.c:1781
HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc)
Definition: usp10.c:1003
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:1774
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:3282
HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *logtovis)
Definition: usp10.c:3715
static BOOL requires_fallback(HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, const WCHAR *pwcInChars, int cChars)
Definition: usp10.c:1855
static void find_fallback_font(enum usp10_script scriptid, WCHAR *FaceName)
Definition: usp10.c:1882
HRESULT WINAPI ScriptBreak(const WCHAR *chars, int count, const SCRIPT_ANALYSIS *sa, SCRIPT_LOGATTR *la)
Definition: usp10.c:3003
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 2368 of file usp10.c.

2369{
2370 int item;
2371 int runningX = 0;
2372 StringAnalysis* analysis = ssa;
2373
2374 TRACE("(%p), %d, %d, (%p)\n", ssa, icp, fTrailing, pX);
2375
2376 if (!ssa || !pX) return S_FALSE;
2377 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
2378
2379 /* icp out of range */
2380 if(icp < 0)
2381 {
2383 return E_INVALIDARG;
2384 }
2385
2386 for(item=0; item<analysis->numItems; item++)
2387 {
2388 int CP, i;
2389 int offset;
2390
2391 i = analysis->logical2visual[item];
2392 CP = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
2393 /* initialize max extents for uninitialized runs */
2394 if (analysis->glyphs[i].iMaxPosX == -1)
2395 {
2396 if (analysis->pItem[i].a.fRTL)
2397 ScriptCPtoX(0, FALSE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2398 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2399 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2400 else
2401 ScriptCPtoX(CP, TRUE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2402 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2403 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2404 }
2405
2406 if (icp >= analysis->pItem[i+1].iCharPos || icp < analysis->pItem[i].iCharPos)
2407 {
2408 runningX += analysis->glyphs[i].iMaxPosX;
2409 continue;
2410 }
2411
2412 icp -= analysis->pItem[i].iCharPos;
2413 ScriptCPtoX(icp, fTrailing, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2414 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2415 &analysis->pItem[i].a, &offset);
2416 runningX += offset;
2417
2418 *pX = runningX;
2419 return S_OK;
2420 }
2421
2422 /* icp out of range */
2424 return E_INVALIDARG;
2425}
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:2606
#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 2513 of file usp10.c.

2514{
2515 StringAnalysis* analysis;
2516 BOOL invalid;
2517 int i;
2518
2519 TRACE("(%p)\n", pssa);
2520
2521 if (!pssa || !(analysis = *pssa)) return E_INVALIDARG;
2522
2524
2525 if (analysis->glyphs)
2526 {
2527 for (i = 0; i < analysis->numItems; i++)
2528 {
2529 free(analysis->glyphs[i].glyphs);
2530 free(analysis->glyphs[i].pwLogClust);
2531 free(analysis->glyphs[i].piAdvance);
2532 free(analysis->glyphs[i].psva);
2533 free(analysis->glyphs[i].pGoffset);
2534 if (analysis->glyphs[i].fallbackFont)
2535 DeleteObject(analysis->glyphs[i].fallbackFont);
2536 ScriptFreeCache((SCRIPT_CACHE *)&analysis->glyphs[i].sc);
2537 }
2538 free(analysis->glyphs);
2539 }
2540
2541 free(analysis->pItem);
2542 free(analysis->logattrs);
2543 free(analysis->logical2visual);
2544 free(analysis);
2545
2546 if (invalid) return E_INVALIDARG;
2547 return S_OK;
2548}
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 3767 of file usp10.c.

3768{
3769 int i, j, next = 0;
3770 StringAnalysis *analysis = ssa;
3771
3772 TRACE("%p, %p\n", ssa, piDx);
3773
3774 if (!analysis) return S_FALSE;
3775 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
3776
3777 for (i = 0; i < analysis->numItems; i++)
3778 {
3779 int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
3780 int direction = 1;
3781
3782 if (analysis->pItem[i].a.fRTL && ! analysis->pItem[i].a.fLogicalOrder)
3783 direction = -1;
3784
3785 for (j = 0; j < cChar; j++)
3786 {
3787 int k;
3788 int glyph = analysis->glyphs[i].pwLogClust[j];
3789 int clust_size = get_cluster_size(analysis->glyphs[i].pwLogClust,
3790 cChar, j, direction, NULL, NULL);
3791 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);
3792
3793 for (k = 0; k < clust_size; k++)
3794 {
3795 piDx[next] = advance / clust_size;
3796 next++;
3797 if (k) j++;
3798 }
3799 }
3800 }
3801 return S_OK;
3802}

Referenced by EDIT_BuildLineDefs_ML(), and LpkGetTextExtentExPoint().

◆ ScriptStringGetOrder()

HRESULT WINAPI ScriptStringGetOrder ( SCRIPT_STRING_ANALYSIS  ssa,
UINT *  order 
)

Definition at line 3924 of file usp10.c.

3925{
3926 int i, j;
3927 unsigned int k;
3928 StringAnalysis *analysis = ssa;
3929
3930 TRACE("(%p)\n", ssa);
3931
3932 if (!analysis) return S_FALSE;
3933 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
3934
3935 /* FIXME: handle RTL scripts */
3936 for (i = 0, k = 0; i < analysis->numItems; i++)
3937 for (j = 0; j < analysis->glyphs[i].numGlyphs; j++, k++)
3938 order[k] = k;
3939
3940 return S_OK;
3941}
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 2323 of file usp10.c.

2331{
2332 StringAnalysis *analysis;
2333 int item;
2334 HRESULT hr;
2335
2336 TRACE("(%p,%d,%d,0x%08x,%s,%d,%d,%d)\n",
2337 ssa, iX, iY, uOptions, wine_dbgstr_rect(prc), iMinSel, iMaxSel, fDisabled);
2338
2339 if (!(analysis = ssa)) return E_INVALIDARG;
2340 if (!(analysis->ssa_flags & SSA_GLYPHS)) return E_INVALIDARG;
2341
2342 for (item = 0; item < analysis->numItems; item++)
2343 {
2344 hr = SS_ItemOut( ssa, iX, iY, analysis->logical2visual[item], -1, -1, uOptions, prc, FALSE, fDisabled);
2345 if (FAILED(hr))
2346 return hr;
2347 }
2348
2349 if (iMinSel < iMaxSel && (iMinSel > 0 || iMaxSel > 0))
2350 {
2351 if (iMaxSel > 0 && iMinSel < 0)
2352 iMinSel = 0;
2353 for (item = 0; item < analysis->numItems; item++)
2354 {
2355 hr = SS_ItemOut( ssa, iX, iY, analysis->logical2visual[item], iMinSel, iMaxSel, uOptions, prc, TRUE, fDisabled);
2356 if (FAILED(hr))
2357 return hr;
2358 }
2359 }
2360
2361 return S_OK;
2362}
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:2156
_Out_ LPRECT prc
Definition: ntgdi.h:1658

Referenced by EDIT_PaintLine(), and test_ScriptString().

◆ ScriptStringValidate()

HRESULT WINAPI ScriptStringValidate ( SCRIPT_STRING_ANALYSIS  ssa)

Definition at line 3817 of file usp10.c.

3818{
3819 StringAnalysis *analysis = ssa;
3820
3821 TRACE("(%p)\n", ssa);
3822
3823 if (!analysis) return E_INVALIDARG;
3825}

◆ ScriptStringXtoCP()

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

Definition at line 2431 of file usp10.c.

2432{
2433 StringAnalysis* analysis = ssa;
2434 int item;
2435
2436 TRACE("(%p), %d, (%p), (%p)\n", ssa, iX, piCh, piTrailing);
2437
2438 if (!ssa || !piCh || !piTrailing) return S_FALSE;
2439 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
2440
2441 /* out of range */
2442 if(iX < 0)
2443 {
2444 if (analysis->pItem[0].a.fRTL)
2445 {
2446 *piCh = 1;
2447 *piTrailing = FALSE;
2448 }
2449 else
2450 {
2451 *piCh = -1;
2452 *piTrailing = TRUE;
2453 }
2454 return S_OK;
2455 }
2456
2457 for(item=0; item<analysis->numItems; item++)
2458 {
2459 int i;
2460 int CP;
2461
2462 for (i = 0; i < analysis->numItems && analysis->logical2visual[i] != item; i++)
2463 /* nothing */;
2464
2465 CP = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
2466 /* initialize max extents for uninitialized runs */
2467 if (analysis->glyphs[i].iMaxPosX == -1)
2468 {
2469 if (analysis->pItem[i].a.fRTL)
2470 ScriptCPtoX(0, FALSE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2471 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2472 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2473 else
2474 ScriptCPtoX(CP, TRUE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2475 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2476 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2477 }
2478
2479 if (iX > analysis->glyphs[i].iMaxPosX)
2480 {
2481 iX -= analysis->glyphs[i].iMaxPosX;
2482 continue;
2483 }
2484
2485 ScriptXtoCP(iX, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2486 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2487 &analysis->pItem[i].a, piCh, piTrailing);
2488 *piCh += analysis->pItem[i].iCharPos;
2489
2490 return S_OK;
2491 }
2492
2493 /* out of range */
2494 *piCh = analysis->pItem[analysis->numItems].iCharPos;
2495 *piTrailing = FALSE;
2496
2497 return S_OK;
2498}
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:2810

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 3557 of file usp10.c.

3561{
3562 HRESULT hr;
3563 INT i, dir = 1;
3564 INT *lpDx;
3565 WORD *reordered_glyphs = (WORD *)pwGlyphs;
3566
3567 TRACE("(%p, %p, %d, %d, %08x, %s, %p, %p, %d, %p, %d, %p, %p, %p)\n",
3568 hdc, psc, x, y, fuOptions, wine_dbgstr_rect(lprc), psa, pwcReserved, iReserved, pwGlyphs, cGlyphs,
3569 piAdvance, piJustify, pGoffset);
3570
3571 if (!hdc || !psc) return E_INVALIDARG;
3572 if (!piAdvance || !psa || !pwGlyphs) return E_INVALIDARG;
3573 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3574
3575 fuOptions &= ETO_CLIPPED | ETO_OPAQUE;
3576 fuOptions |= ETO_IGNORELANGUAGE;
3577 if (!psa->fNoGlyphIndex && *psc && ((ScriptCache *)*psc)->sfnt)
3578 fuOptions |= ETO_GLYPH_INDEX; /* We do actually have glyph indices */
3579
3580 if (!(lpDx = calloc(cGlyphs, 2 * sizeof(*lpDx))))
3581 return E_OUTOFMEMORY;
3582 fuOptions |= ETO_PDY;
3583
3584 if (psa->fRTL && psa->fLogicalOrder)
3585 {
3586 if (!(reordered_glyphs = calloc(cGlyphs, sizeof(*reordered_glyphs))))
3587 {
3588 free( lpDx );
3589 return E_OUTOFMEMORY;
3590 }
3591
3592 for (i = 0; i < cGlyphs; i++)
3593 reordered_glyphs[i] = pwGlyphs[cGlyphs - 1 - i];
3594 dir = -1;
3595 }
3596
3597 for (i = 0; i < cGlyphs; i++)
3598 {
3599 int orig_index = (dir > 0) ? i : cGlyphs - 1 - i;
3600 lpDx[i * 2] = piAdvance[orig_index];
3601 lpDx[i * 2 + 1] = 0;
3602
3603 if (pGoffset)
3604 {
3605 if (i == 0)
3606 {
3607 x += pGoffset[orig_index].du * dir;
3608 y += pGoffset[orig_index].dv;
3609 }
3610 else
3611 {
3612 lpDx[(i - 1) * 2] += pGoffset[orig_index].du * dir;
3613 lpDx[(i - 1) * 2 + 1] += pGoffset[orig_index].dv;
3614 }
3615 lpDx[i * 2] -= pGoffset[orig_index].du * dir;
3616 lpDx[i * 2 + 1] -= pGoffset[orig_index].dv;
3617 }
3618 }
3619
3620 if (!ExtTextOutW(hdc, x, y, fuOptions, lprc, reordered_glyphs, cGlyphs, lpDx))
3621 hr = S_FALSE;
3622
3623 if (reordered_glyphs != pwGlyphs) free( reordered_glyphs );
3624 free(lpDx);
3625
3626 return hr;
3627}
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 2810 of file usp10.c.

2819{
2820 int direction = 1;
2821 int iPosX;
2822 int i;
2823 int glyph_index, cluster_index;
2824 int cluster_size;
2825
2826 TRACE("(%d,%d,%d,%p,%p,%p,%p,%p,%p)\n",
2827 iX, cChars, cGlyphs, pwLogClust, psva, piAdvance,
2828 psa, piCP, piTrailing);
2829
2830 if (psa->fRTL && ! psa->fLogicalOrder)
2831 direction = -1;
2832
2833 /* Handle an iX < 0 */
2834 if (iX < 0)
2835 {
2836 if (direction < 0)
2837 {
2838 *piCP = cChars;
2839 *piTrailing = 0;
2840 }
2841 else
2842 {
2843 *piCP = -1;
2844 *piTrailing = 1;
2845 }
2846 return S_OK;
2847 }
2848
2849 /* Looking for non-reversed clusters in a reversed string */
2850 if (direction < 0)
2851 {
2852 int max_clust = pwLogClust[0];
2853 for (i=0; i< cChars; i++)
2854 if (pwLogClust[i] > max_clust)
2855 {
2856 FIXME("We do not handle non reversed clusters properly\n");
2857 break;
2858 }
2859 }
2860
2861 /* find the glyph_index based in iX */
2862 if (direction > 0)
2863 {
2864 for (glyph_index = -1, iPosX = iX; iPosX >=0 && glyph_index < cGlyphs; iPosX -= piAdvance[glyph_index+1], glyph_index++)
2865 ;
2866 }
2867 else
2868 {
2869 for (glyph_index = -1, iPosX = iX; iPosX > 0 && glyph_index < cGlyphs; iPosX -= piAdvance[glyph_index+1], glyph_index++)
2870 ;
2871 }
2872
2873 TRACE("iPosX %i -> glyph_index %i (%i)\n", iPosX, glyph_index, cGlyphs);
2874
2875 *piTrailing = 0;
2876 if (glyph_index >= 0 && glyph_index < cGlyphs)
2877 {
2878 /* find the cluster */
2879 if (direction > 0 )
2880 for (i = 0, cluster_index = pwLogClust[0]; i < cChars && pwLogClust[i] <= glyph_index; cluster_index=pwLogClust[i++])
2881 ;
2882 else
2883 for (i = 0, cluster_index = pwLogClust[0]; i < cChars && pwLogClust[i] >= glyph_index; cluster_index=pwLogClust[i++])
2884 ;
2885
2886 TRACE("cluster_index %i\n", cluster_index);
2887
2888 if (direction < 0 && iPosX >= 0 && glyph_index != cluster_index)
2889 {
2890 /* We are off the end of the string */
2891 *piCP = -1;
2892 *piTrailing = 1;
2893 return S_OK;
2894 }
2895
2896 get_cluster_data(pwLogClust, cChars, cluster_index, &cluster_size, &i);
2897
2898 TRACE("first char index %i\n",i);
2900 {
2901 /* Check trailing */
2902 if (glyph_index != cluster_index ||
2903 (direction > 0 && abs(iPosX) <= (piAdvance[glyph_index] / 2)) ||
2904 (direction < 0 && abs(iPosX) >= (piAdvance[glyph_index] / 2)))
2905 *piTrailing = cluster_size;
2906 }
2907 else
2908 {
2909 if (cluster_size > 1)
2910 {
2911 /* Be part way through the glyph cluster based on size and position */
2912 int cluster_advance = get_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, cluster_index, direction);
2913 double cluster_part_width = cluster_advance / (float)cluster_size;
2914 double adv;
2915 int part_index;
2916
2917 /* back up to the beginning of the cluster */
2918 for (adv = iPosX, part_index = cluster_index; part_index <= glyph_index; part_index++)
2919 adv += piAdvance[part_index];
2920 if (adv > iX) adv = iX;
2921
2922 TRACE("Multi-char cluster, no snap\n");
2923 TRACE("cluster size %i, pre-cluster iPosX %f\n",cluster_size, adv);
2924 TRACE("advance %i divides into %f per char\n", cluster_advance, cluster_part_width);
2925 if (direction > 0)
2926 {
2927 for (part_index = 0; adv >= 0; adv-=cluster_part_width, part_index++)
2928 ;
2929 if (part_index) part_index--;
2930 }
2931 else
2932 {
2933 for (part_index = 0; adv > 0; adv-=cluster_part_width, part_index++)
2934 ;
2935 if (part_index > cluster_size)
2936 {
2937 adv += cluster_part_width;
2938 part_index=cluster_size;
2939 }
2940 }
2941
2942 TRACE("base_char %i part_index %i, leftover advance %f\n",i, part_index, adv);
2943
2944 if (direction > 0)
2945 i += part_index;
2946 else
2947 i += (cluster_size - part_index);
2948
2949 /* Check trailing */
2950 if ((direction > 0 && fabs(adv) <= (cluster_part_width / 2.0)) ||
2951 (direction < 0 && adv && fabs(adv) >= (cluster_part_width / 2.0)))
2952 *piTrailing = 1;
2953 }
2954 else
2955 {
2956 /* Check trailing */
2957 if ((direction > 0 && abs(iPosX) <= (piAdvance[glyph_index] / 2)) ||
2958 (direction < 0 && abs(iPosX) >= (piAdvance[glyph_index] / 2)))
2959 *piTrailing = 1;
2960 }
2961 }
2962 }
2963 else
2964 {
2965 TRACE("Point falls outside of string\n");
2966 if (glyph_index < 0)
2967 i = cChars-1;
2968 else /* (glyph_index >= cGlyphs) */
2969 i = cChars;
2970
2971 /* If not snapping in the reverse direction (such as Hebrew) Then 0
2972 point flow to the next character */
2973 if (direction < 0)
2974 {
2975 if (!scriptInformation[psa->eScript].props.fNeedsCaretInfo && abs(iPosX) == piAdvance[glyph_index])
2976 i++;
2977 else
2978 *piTrailing = 1;
2979 }
2980 }
2981
2982 *piCP = i;
2983
2984 TRACE("*piCP=%d\n", *piCP);
2985 TRACE("*piTrailing=%d\n", *piTrailing);
2986 return S_OK;
2987}
_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:2749
static BOOL get_cluster_data(const WORD *pwLogClust, int cChars, int cluster_index, int *cluster_size, int *start_index)
Definition: usp10.c:2716
#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 2156 of file usp10.c.

2166{
2167 StringAnalysis *analysis;
2168 int off_x = 0;
2169 HRESULT hr;
2170 COLORREF BkColor = 0x0;
2171 COLORREF TextColor = 0x0;
2172 INT BkMode = 0;
2173 INT runStart, runEnd;
2174 INT iGlyph, cGlyphs;
2175 HFONT oldFont = 0x0;
2176 RECT crc;
2177 int i;
2178
2179 TRACE("(%p,%d,%d,%d,%d,%d, 0x%1x, %d, %d)\n",
2180 ssa, iX, iY, iItem, cStart, cEnd, uOptions, fSelected, fDisabled);
2181
2182 if (!(analysis = ssa)) return E_INVALIDARG;
2183
2184 if ((cStart >= 0 && analysis->pItem[iItem+1].iCharPos <= cStart) ||
2185 (cEnd >= 0 && analysis->pItem[iItem].iCharPos >= cEnd))
2186 return S_OK;
2187
2188 if (prc)
2189 memcpy(&crc, prc, sizeof(crc));
2190 if (fSelected)
2191 {
2192 BkMode = GetBkMode(analysis->hdc);
2193 SetBkMode( analysis->hdc, OPAQUE);
2194 BkColor = GetBkColor(analysis->hdc);
2196 if (!fDisabled)
2197 {
2198 TextColor = GetTextColor(analysis->hdc);
2200 }
2201 }
2202 if (analysis->glyphs[iItem].fallbackFont)
2203 oldFont = SelectObject(analysis->hdc, analysis->glyphs[iItem].fallbackFont);
2204
2205 if (cStart >= 0 && analysis->pItem[iItem+1].iCharPos > cStart && analysis->pItem[iItem].iCharPos <= cStart)
2206 runStart = cStart - analysis->pItem[iItem].iCharPos;
2207 else
2208 runStart = 0;
2209 if (cEnd >= 0 && analysis->pItem[iItem+1].iCharPos > cEnd && analysis->pItem[iItem].iCharPos <= cEnd)
2210 runEnd = (cEnd-1) - analysis->pItem[iItem].iCharPos;
2211 else
2212 runEnd = (analysis->pItem[iItem+1].iCharPos - analysis->pItem[iItem].iCharPos) - 1;
2213
2214 if (analysis->pItem[iItem].a.fRTL)
2215 {
2216 if (cEnd >= 0 && cEnd < analysis->pItem[iItem+1].iCharPos)
2217 ScriptStringCPtoX(ssa, cEnd, FALSE, &off_x);
2218 else
2219 ScriptStringCPtoX(ssa, analysis->pItem[iItem+1].iCharPos-1, TRUE, &off_x);
2220 crc.left = iX + off_x;
2221 }
2222 else
2223 {
2224 if (cStart >=0 && runStart)
2225 ScriptStringCPtoX(ssa, cStart, FALSE, &off_x);
2226 else
2227 ScriptStringCPtoX(ssa, analysis->pItem[iItem].iCharPos, FALSE, &off_x);
2228 crc.left = iX + off_x;
2229 }
2230
2231 if (analysis->pItem[iItem].a.fRTL)
2232 iGlyph = analysis->glyphs[iItem].pwLogClust[runEnd];
2233 else
2234 iGlyph = analysis->glyphs[iItem].pwLogClust[runStart];
2235
2236 if (analysis->pItem[iItem].a.fRTL)
2237 cGlyphs = analysis->glyphs[iItem].pwLogClust[runStart] - iGlyph;
2238 else
2239 cGlyphs = analysis->glyphs[iItem].pwLogClust[runEnd] - iGlyph;
2240
2241 cGlyphs++;
2242
2243 /* adjust for cluster glyphs when starting */
2244 if (analysis->pItem[iItem].a.fRTL)
2245 i = analysis->pItem[iItem+1].iCharPos - 1;
2246 else
2247 i = analysis->pItem[iItem].iCharPos;
2248
2249 for (; i >=analysis->pItem[iItem].iCharPos && i < analysis->pItem[iItem+1].iCharPos; (analysis->pItem[iItem].a.fRTL)?i--:i++)
2250 {
2251 if (analysis->glyphs[iItem].pwLogClust[i - analysis->pItem[iItem].iCharPos] == iGlyph)
2252 {
2253 if (analysis->pItem[iItem].a.fRTL)
2254 ScriptStringCPtoX(ssa, i, TRUE, &off_x);
2255 else
2256 ScriptStringCPtoX(ssa, i, FALSE, &off_x);
2257 break;
2258 }
2259 }
2260
2261 if (cEnd < 0 || scriptInformation[analysis->pItem[iItem].a.eScript].props.fNeedsCaretInfo)
2262 {
2263 INT direction;
2264 INT clust_glyph;
2265
2266 clust_glyph = iGlyph + cGlyphs;
2267 if (analysis->pItem[iItem].a.fRTL)
2268 direction = -1;
2269 else
2270 direction = 1;
2271
2272 while(clust_glyph < analysis->glyphs[iItem].numGlyphs &&
2273 !does_glyph_start_cluster(analysis->glyphs[iItem].psva, analysis->glyphs[iItem].pwLogClust, (analysis->pItem[iItem+1].iCharPos - analysis->pItem[iItem].iCharPos), clust_glyph, direction))
2274 {
2275 cGlyphs++;
2276 clust_glyph++;
2277 }
2278 }
2279
2280 hr = ScriptTextOut(analysis->hdc,
2281 (SCRIPT_CACHE *)&analysis->glyphs[iItem].sc, iX + off_x,
2282 iY, uOptions, &crc, &analysis->pItem[iItem].a, NULL, 0,
2283 &analysis->glyphs[iItem].glyphs[iGlyph], cGlyphs,
2284 &analysis->glyphs[iItem].piAdvance[iGlyph], NULL,
2285 &analysis->glyphs[iItem].pGoffset[iGlyph]);
2286
2287 TRACE("ScriptTextOut hr=%08lx\n", hr);
2288
2289 if (fSelected)
2290 {
2291 SetBkColor(analysis->hdc, BkColor);
2292 SetBkMode( analysis->hdc, BkMode);
2293 if (!fDisabled)
2294 SetTextColor(analysis->hdc, TextColor);
2295 }
2296 if (analysis->glyphs[iItem].fallbackFont)
2297 SelectObject(analysis->hdc, oldFont);
2298
2299 return hr;
2300}
HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrailing, int *pX)
Definition: usp10.c:2368
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:3557
#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 881 of file usp10.c.

882{
883 const struct usp10_script_range *range = value;
884 const DWORD *ch = key;
885
886 if (*ch < range->rangeFirst)
887 return -1;
888 if (*ch > range->rangeLast)
889 return 1;
890 return 0;
891}
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 967 of file usp10.c.

968{
970 WORD *ptr;
971 INT k;
972
973 if (pwLogClust[0] < pwLogClust[cChars-1])
974 fgs.ascending = TRUE;
975 else
976 fgs.ascending = FALSE;
977
978 fgs.target = target;
979 ptr = bsearch(&fgs, pwLogClust, cChars, sizeof(WORD), compare_FindGlyph);
980
981 if (!ptr)
982 return -1;
983
984 for (k = (ptr - pwLogClust)-1; k >= 0 && pwLogClust[k] == target; k--)
985 ;
986 k++;
987
988 return k;
989}
static int __cdecl compare_FindGlyph(const void *a, const void *b)
Definition: usp10.c:951
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