ReactOS 0.4.15-dev-7928-g68a8619
usp10.c File Reference
#include <stdarg.h>
#include <stdlib.h>
#include <math.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "winreg.h"
#include "usp10.h"
#include "usp10_internal.h"
#include "wine/debug.h"
#include "wine/heap.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)
 

Variables

static const struct usp10_script_range script_ranges []
 
const scriptData scriptInformation []
 
static const SCRIPT_PROPERTIESscript_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 704 of file usp10.c.

705{
708};
@ SCRIPT_STRING_ANALYSIS_FLAGS_SIZE
Definition: usp10.c:706
@ SCRIPT_STRING_ANALYSIS_FLAGS_INVALID
Definition: usp10.c:707

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

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

Referenced by ScriptItemize(), and ScriptItemizeOpenType().

◆ base_indic()

static enum usp10_script base_indic ( enum usp10_script  script)
inlinestatic

Definition at line 1310 of file usp10.c.

1311{
1312 switch (script)
1313 {
1314 case Script_Devanagari:
1316 case Script_Bengali:
1319 case Script_Gurmukhi:
1321 case Script_Gujarati:
1324 case Script_Oriya:
1326 case Script_Tamil:
1328 case Script_Telugu:
1330 case Script_Kannada:
1332 case Script_Malayalam:
1334 default:
1335 return Script_Undefined;
1336 };
1337}
script
Definition: msipriv.h:383
@ Script_Kannada_Numeric
@ Script_Bengali_Numeric
@ Script_Telugu
@ Script_Gurmukhi_Numeric
@ Script_Devanagari_Numeric
@ Script_Telugu_Numeric
@ Script_Malayalam_Numeric
@ Script_Gujarati_Numeric
@ Script_Bengali
@ Script_Tamil_Numeric
@ Script_Oriya_Numeric
@ Script_Oriya
@ Script_Kannada
@ Script_Gurmukhi
@ Script_Tamil
@ Script_Bengali_Currency
@ Script_Gujarati_Currency
@ Script_Gujarati
@ Script_Devanagari
@ Script_Malayalam

Referenced by _ItemizeInternal().

◆ compare_FindGlyph()

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

Definition at line 1028 of file usp10.c.

1029{
1031 const WORD *idx= (WORD*)b;
1032 int rc = 0;
1033
1034 if ( find->target > *idx)
1035 rc = 1;
1036 else if (find->target < *idx)
1037 rc = -1;
1038
1039 if (!find->ascending)
1040 rc *= -1;
1041 return rc;
1042}
static TAGID TAGID find
Definition: db.cpp:155
unsigned int idx
Definition: utils.c:41
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 946 of file usp10.c.

947{
948 if (index < end-1 && IS_SURROGATE_PAIR(str[index],str[index+1]))
949 {
950 DWORD ch = 0x10000 + ((str[index] - 0xd800) << 10) + (str[index+1] - 0xdc00);
951 TRACE("Surrogate Pair %x %x => %x\n",str[index], str[index+1], ch);
952 return ch;
953 }
954 return 0;
955}
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint end
Definition: gl.h:1545
#define IS_SURROGATE_PAIR(high, low)
Definition: winnls.h:681

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

2190{
2191 if (pva[glyph].fClusterStart)
2192 return TRUE;
2194 return TRUE;
2195
2196 return FALSE;
2197}
int USP10_FindGlyphInLogClust(const WORD *pwLogClust, int cChars, WORD target)
Definition: usp10.c:1044
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR int cChars
Definition: usp10.c:64
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR int int WORD * pwLogClust
Definition: usp10.c:64

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

1962{
1963 HKEY hkey;
1964
1965 if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Uniscribe\\Fallback", &hkey))
1966 {
1967 static const WCHAR szFmt[] = {'%','x',0};
1968 WCHAR value[10];
1969 DWORD count = LF_FACESIZE * sizeof(WCHAR);
1970 DWORD type;
1971
1972 swprintf(value, szFmt, scriptInformation[scriptid].scriptTag);
1973 if (RegQueryValueExW(hkey, value, 0, &type, (BYTE *)FaceName, &count))
1974 lstrcpyW(FaceName,scriptInformation[scriptid].fallbackFont);
1975 RegCloseKey(hkey);
1976 }
1977 else
1978 lstrcpyW(FaceName,scriptInformation[scriptid].fallbackFont);
1979}
#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 GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
Definition: pdh_main.c:94
#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 810 of file usp10.c.

811{
812 *sfp = sc->sfp;
813}
SCRIPT_FONTPROPERTIES sfp

Referenced by ScriptGetFontProperties().

◆ get_cache_glyph()

static WORD get_cache_glyph ( SCRIPT_CACHE psc,
DWORD  c 
)
inlinestatic

Definition at line 825 of file usp10.c.

826{
827 CacheGlyphPage *page = ((ScriptCache *)*psc)->page[c / 0x10000];
828 WORD *block;
829
830 if (!page) return 0;
831 block = page->glyphs[(c % 0x10000) >> GLYPH_BLOCK_SHIFT];
832 if (!block) return 0;
833 return block[(c % 0x10000) & GLYPH_BLOCK_MASK];
834}
const GLubyte * c
Definition: glext.h:8905
static SCRIPT_CACHE * psc
Definition: usp10.c:64
Definition: module.h:576
#define GLYPH_BLOCK_SHIFT
#define GLYPH_BLOCK_MASK
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 847 of file usp10.c.

848{
849 static const ABC nil;
850 ABC *block = ((ScriptCache *)*psc)->widths[glyph >> GLYPH_BLOCK_SHIFT];
851
852 if (!block || !memcmp(&block[glyph & GLYPH_BLOCK_MASK], &nil, sizeof(ABC))) return FALSE;
853 memcpy(abc, &block[glyph & GLYPH_BLOCK_MASK], sizeof(ABC));
854 return TRUE;
855}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static UINT UINT LPWORD LPABC abc
Definition: font.c:44
#define nil
Definition: compat.h:23
Definition: wingdi.h:1410

Referenced by ScriptGetGlyphABCWidth(), and ScriptPlaceOpenType().

◆ get_cache_height()

static LONG get_cache_height ( SCRIPT_CACHE psc)
inlinestatic

Definition at line 815 of file usp10.c.

816{
817 return ((ScriptCache *)*psc)->tm.tmHeight;
818}

Referenced by ScriptCacheGetHeight().

◆ get_cache_pitch_family()

static BYTE get_cache_pitch_family ( SCRIPT_CACHE psc)
inlinestatic

Definition at line 820 of file usp10.c.

821{
822 return ((ScriptCache *)*psc)->tm.tmPitchAndFamily;
823}

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

971{
972 static const WCHAR latin_punc[] = {'#','$','&','\'',',',';','<','>','?','@','\\','^','_','`','{','|','}','~', 0x00a0, 0};
974 WORD type = 0, type2 = 0;
975 DWORD ch;
976
977 *consumed = 1;
978
979 if (str[index] == 0xc || str[index] == 0x20 || str[index] == 0x202f)
980 return Script_CR;
981
982 /* These punctuation characters are separated out as Latin punctuation */
983 if (wcschr(latin_punc,str[index]))
984 return Script_Punctuation2;
985
986 /* These chars are itemized as Punctuation by Windows */
987 if (str[index] == 0x2212 || str[index] == 0x2044)
988 return Script_Punctuation;
989
990 /* Currency Symbols by Unicode point */
991 switch (str[index])
992 {
993 case 0x09f2:
994 case 0x09f3: return Script_Bengali_Currency;
995 case 0x0af1: return Script_Gujarati_Currency;
996 case 0x0e3f: return Script_Thai_Currency;
997 case 0x20aa: return Script_Hebrew_Currency;
998 case 0x20ab: return Script_Vietnamese_Currency;
999 case 0xfb29: return Script_Hebrew_Currency;
1000 }
1001
1003 GetStringTypeW(CT_CTYPE2, &str[index], 1, &type2);
1004
1005 if (type == 0)
1006 return SCRIPT_UNDEFINED;
1007
1008 if (type & C1_CNTRL)
1009 return Script_Control;
1010
1012 if (ch)
1013 *consumed = 2;
1014 else
1015 ch = str[index];
1016
1019 return (*consumed == 2) ? Script_Surrogates : Script_Undefined;
1020
1021 if (range->numericScript && (type & C1_DIGIT || type2 == C2_ARABICNUMBER))
1022 return range->numericScript;
1023 if (range->punctScript && type & C1_PUNCT)
1024 return range->punctScript;
1025 return range->script;
1026}
#define ARRAY_SIZE(A)
Definition: main.h:33
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:946
static int __cdecl usp10_compare_script_range(const void *key, const void *value)
Definition: usp10.c:957
GLenum GLint * range
Definition: glext.h:7539
#define C1_CNTRL
Definition: unicode.h:36
#define C1_DIGIT
Definition: unicode.h:33
#define C1_PUNCT
Definition: unicode.h:35
BOOL WINAPI GetStringTypeW(DWORD type, LPCWSTR src, INT count, LPWORD chartype)
Definition: lang.c:1709
#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:255
#define CT_CTYPE2
Definition: winnls.h:238
#define CT_CTYPE1
Definition: winnls.h:237

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

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

2761{
2762 int size = 0;
2763 int i;
2764
2765 for (i = 0; i < cChars; i++)
2766 {
2767 if (pwLogClust[i] == cluster_index)
2768 {
2769 if (!size && start_index)
2770 {
2771 *start_index = i;
2772 if (!cluster_size)
2773 return TRUE;
2774 }
2775 size++;
2776 }
2777 else if (size) break;
2778 }
2779 if (cluster_size)
2780 *cluster_size = size;
2781
2782 return (size > 0);
2783}
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 2594 of file usp10.c.

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

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

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

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

◆ getGivenTabWidth()

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

Definition at line 1860 of file usp10.c.

1861{
1862 int defWidth;
1863 int cTabStops=0;
1864 INT *lpTabPos = NULL;
1865 INT nTabOrg = 0;
1866 INT x = 0;
1867
1868 if (pTabdef)
1869 lpTabPos = pTabdef->pTabStops;
1870
1871 if (pTabdef && pTabdef->iTabOrigin)
1872 {
1873 if (pTabdef->iScale)
1874 nTabOrg = (pTabdef->iTabOrigin * pTabdef->iScale)/4;
1875 else
1876 nTabOrg = pTabdef->iTabOrigin * psc->tm.tmAveCharWidth;
1877 }
1878
1879 if (pTabdef)
1880 cTabStops = pTabdef->cTabStops;
1881
1882 if (cTabStops == 1)
1883 {
1884 if (pTabdef->iScale)
1885 defWidth = ((pTabdef->pTabStops[0])*pTabdef->iScale) / 4;
1886 else
1887 defWidth = (pTabdef->pTabStops[0])*psc->tm.tmAveCharWidth;
1888 cTabStops = 0;
1889 }
1890 else
1891 {
1892 if (pTabdef->iScale)
1893 defWidth = (32 * pTabdef->iScale) / 4;
1894 else
1895 defWidth = 8 * psc->tm.tmAveCharWidth;
1896 }
1897
1898 for (; cTabStops>0 ; lpTabPos++, cTabStops--)
1899 {
1900 int position = *lpTabPos;
1901 if (position < 0)
1902 position = -1 * position;
1903 if (pTabdef->iScale)
1904 position = (position * pTabdef->iScale) / 4;
1905 else
1906 position = position * psc->tm.tmAveCharWidth;
1907
1908 if( nTabOrg + position > current_x)
1909 {
1910 if( position >= 0)
1911 {
1912 /* a left aligned tab */
1913 x = (nTabOrg + position) - current_x;
1914 break;
1915 }
1916 else
1917 {
1918 FIXME("Negative tabstop\n");
1919 break;
1920 }
1921 }
1922 }
1923 if ((!cTabStops) && (defWidth > 0))
1924 x =((((current_x - nTabOrg) / defWidth)+1) * defWidth) - current_x;
1925 else if ((!cTabStops) && (defWidth < 0))
1926 FIXME("TODO: Negative defWidth\n");
1927
1928 return x;
1929}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
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 866 of file usp10.c.

867{
868 ScriptCache *sc;
869 unsigned size;
870 LOGFONTW lf;
871
872 if (!psc) return E_INVALIDARG;
873 if (*psc) return S_OK;
874 if (!hdc) return E_PENDING;
875
876 if (!GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf))
877 {
878 return E_INVALIDARG;
879 }
880 /* Ensure canonical result by zeroing extra space in lfFaceName */
882 memset(lf.lfFaceName + size, 0, sizeof(lf.lfFaceName) - size * sizeof(WCHAR));
883
886 {
887 if (!memcmp(&sc->lf, &lf, sizeof(lf)))
888 {
889 sc->refcount++;
891 *psc = sc;
892 return S_OK;
893 }
894 }
896
897 if (!(sc = heap_alloc_zero(sizeof(ScriptCache)))) return E_OUTOFMEMORY;
898 if (!GetTextMetricsW(hdc, &sc->tm))
899 {
900 heap_free(sc);
901 return E_INVALIDARG;
902 }
904 if (size)
905 {
906 sc->otm = heap_alloc(size);
907 sc->otm->otmSize = size;
909 }
910 sc->sfnt = (GetFontData(hdc, MS_MAKE_TAG('h','e','a','d'), 0, NULL, 0)!=GDI_ERROR);
912 {
913 heap_free(sc);
914 return E_INVALIDARG;
915 }
916 sc->lf = lf;
917 sc->refcount = 1;
918 *psc = sc;
919
923 {
924 if (sc != *psc && !memcmp(&sc->lf, &lf, sizeof(lf)))
925 {
926 /* Another thread won the race. Use their cache instead of ours */
927 list_remove(&sc->entry);
928 sc->refcount++;
930 heap_free(*psc);
931 *psc = sc;
932 return S_OK;
933 }
934 }
936 TRACE("<- %p\n", sc);
937 return S_OK;
938}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
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 E_PENDING
Definition: dinput.h:172
#define lstrlenW
Definition: compat.h:750
#define MS_MAKE_TAG(ch0, ch1, ch2, ch3)
Definition: font.c:113
static struct list script_cache_list
Definition: usp10.c:689
static CRITICAL_SECTION cs_script_cache
Definition: usp10.c:681
static BOOL set_cache_font_properties(const HDC hdc, ScriptCache *sc)
Definition: usp10.c:761
uint32_t entry
Definition: isohybrid.c:63
HDC hdc
Definition: main.c:9
#define OBJ_FONT
Definition: objidl.idl:1414
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
OUTLINETEXTMETRICW * otm
struct list entry
TEXTMETRICW tm
DWORD WINAPI GetFontData(HDC hdc, DWORD dwTable, DWORD dwOffset, LPVOID lpvBuffer, DWORD cbData)
Definition: font.c:2654
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
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(), and ScriptShapeOpenType().

◆ is_indic()

static BOOL is_indic ( enum usp10_script  script)
inlinestatic

Definition at line 1305 of file usp10.c.

1306{
1308}

Referenced by _ItemizeInternal().

◆ mirror_char()

static WCHAR mirror_char ( WCHAR  ch)
static

Definition at line 940 of file usp10.c.

941{
943 return ch + wine_mirror_map[wine_mirror_map[ch >> 8] + (ch & 0xff)];
944}
#define DECLSPEC_HIDDEN
Definition: precomp.h:8
const WCHAR DECLSPEC_HIDDEN wine_mirror_map[3544]
Definition: mirror.c:7

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

1936{
1937 /* FIXME: When to properly fallback is still a bit of a mystery */
1938 WORD *glyphs;
1939
1940 if (psa->fNoGlyphIndex)
1941 return FALSE;
1942
1943 if (init_script_cache(hdc, psc) != S_OK)
1944 return FALSE;
1945
1947 return TRUE;
1948
1949 if (!(glyphs = heap_calloc(cChars, sizeof(*glyphs))))
1950 return FALSE;
1951 if (ScriptGetCMap(hdc, psc, pwcInChars, cChars, 0, glyphs) != S_OK)
1952 {
1954 return TRUE;
1955 }
1957
1958 return FALSE;
1959}
HRESULT WINAPI ScriptGetCMap(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcInChars, int cChars, DWORD dwFlags, WORD *pwOutGlyphs)
Definition: usp10.c:3554
static HRESULT init_script_cache(const HDC hdc, SCRIPT_CACHE *psc)
Definition: usp10.c:866
static UINT UINT LPWORD glyphs
Definition: font.c:44
static SCRIPT_CACHE SCRIPT_ANALYSIS * psa
Definition: usp10.c:64
HRESULT SHAPE_CheckFontForRequiredFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa)
Definition: shape.c:3454

Referenced by ScriptStringAnalyse().

◆ script_is_numeric()

static BOOL script_is_numeric ( enum usp10_script  script)
static

Definition at line 1339 of file usp10.c.

1340{
1342}
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 1275 of file usp10.c.

1277{
1279
1280 TRACE("%p, %p, %p\n", sds, sc, ss);
1281
1282 if (!sc || !ss) return E_POINTER;
1283 if (!sds)
1284 {
1285 sds = &psds;
1287 return E_INVALIDARG;
1288 }
1289
1291 sc->fContextDigits = 0;
1292 ss->fDigitSubstitute = 0;
1293
1294 switch (sds->DigitSubstitute) {
1299 return S_OK;
1300 default:
1301 return E_INVALIDARG;
1302 }
1303}
HRESULT WINAPI ScriptRecordDigitSubstitution(LCID locale, SCRIPT_DIGITSUBSTITUTE *sds)
Definition: usp10.c:1209
#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:2365

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

4053{
4054 int i;
4055
4056 FIXME("(%p, %d, %d, %p, %p, %p, %p, %p, %p)\n",
4057 dx, num_chars, num_glyphs, log_clust, sva, advance, sa, abc, justify);
4058
4059 for (i = 0; i < num_chars; i++) justify[i] = advance[i];
4060 return S_OK;
4061}
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 3047 of file usp10.c.

3048{
3049 TRACE("(%s, %d, %p, %p)\n", debugstr_wn(chars, count), count, sa, la);
3050
3051 if (count < 0 || !la) return E_INVALIDARG;
3052 if (count == 0) return E_FAIL;
3053
3054 BREAK_line(chars, count, sa, la);
3055
3056 return S_OK;
3057}
void BREAK_line(const WCHAR *chars, int count, const SCRIPT_ANALYSIS *sa, SCRIPT_LOGATTR *la)
Definition: breaking.c:77
#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 3680 of file usp10.c.

3681{
3682 HRESULT hr;
3683
3684 TRACE("(%p, %p, %p)\n", hdc, psc, height);
3685
3686 if (!height) return E_INVALIDARG;
3687 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3688
3690 return S_OK;
3691}
static LONG get_cache_height(SCRIPT_CACHE *psc)
Definition: usp10.c:815
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
HRESULT hr
Definition: shlfolder.c:183

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

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

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

◆ ScriptFreeCache()

HRESULT WINAPI ScriptFreeCache ( SCRIPT_CACHE psc)

Definition at line 1080 of file usp10.c.

1081{
1082 TRACE("%p\n", psc);
1083
1084 if (psc && *psc)
1085 {
1086 unsigned int i;
1087 INT n;
1088
1090 if (--((ScriptCache *)*psc)->refcount > 0)
1091 {
1093 *psc = NULL;
1094 return S_OK;
1095 }
1098
1099 for (i = 0; i < GLYPH_MAX / GLYPH_BLOCK_SIZE; i++)
1100 {
1101 heap_free(((ScriptCache *)*psc)->widths[i]);
1102 }
1103 for (i = 0; i < NUM_PAGES; i++)
1104 {
1105 unsigned int j;
1106 if (((ScriptCache *)*psc)->page[i])
1107 for (j = 0; j < GLYPH_MAX / GLYPH_BLOCK_SIZE; j++)
1108 heap_free(((ScriptCache *)*psc)->page[i]->glyphs[j]);
1109 heap_free(((ScriptCache *)*psc)->page[i]);
1110 }
1111 heap_free(((ScriptCache *)*psc)->GSUB_Table);
1112 heap_free(((ScriptCache *)*psc)->GDEF_Table);
1113 heap_free(((ScriptCache *)*psc)->CMAP_Table);
1114 heap_free(((ScriptCache *)*psc)->GPOS_Table);
1115 for (n = 0; n < ((ScriptCache *)*psc)->script_count; n++)
1116 {
1117 int j;
1118 for (j = 0; j < ((ScriptCache *)*psc)->scripts[n].language_count; j++)
1119 {
1120 int k;
1121 for (k = 0; k < ((ScriptCache *)*psc)->scripts[n].languages[j].feature_count; k++)
1122 heap_free(((ScriptCache *)*psc)->scripts[n].languages[j].features[k].lookups);
1123 heap_free(((ScriptCache *)*psc)->scripts[n].languages[j].features);
1124 }
1125 for (j = 0; j < ((ScriptCache *)*psc)->scripts[n].default_language.feature_count; j++)
1126 heap_free(((ScriptCache *)*psc)->scripts[n].default_language.features[j].lookups);
1127 heap_free(((ScriptCache *)*psc)->scripts[n].default_language.features);
1128 heap_free(((ScriptCache *)*psc)->scripts[n].languages);
1129 }
1130 heap_free(((ScriptCache *)*psc)->scripts);
1131 heap_free(((ScriptCache *)*psc)->otm);
1132 heap_free(*psc);
1133 *psc = NULL;
1134 }
1135 return S_OK;
1136}
GLdouble n
Definition: glext.h:7729
int k
Definition: mpi.c:3369
#define GLYPH_BLOCK_SIZE
#define GLYPH_MAX
#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 3554 of file usp10.c.

3556{
3557 HRESULT hr;
3558 int i;
3559
3560 TRACE("(%p,%p,%s,%d,0x%x,%p)\n", hdc, psc, debugstr_wn(pwcInChars, cChars),
3562
3563 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3564
3565 hr = S_OK;
3566
3567 for (i = 0; i < cChars; i++)
3568 {
3569 WCHAR inChar;
3570 if (dwFlags == SGCM_RTL)
3571 inChar = mirror_char(pwcInChars[i]);
3572 else
3573 inChar = pwcInChars[i];
3574 if (!(pwOutGlyphs[i] = get_cache_glyph(psc, inChar)))
3575 {
3576 WORD glyph;
3577 if (!hdc) return E_PENDING;
3578 if (GetGlyphIndicesW(hdc, &inChar, 1, &glyph, GGI_MARK_NONEXISTING_GLYPHS) == GDI_ERROR) return S_FALSE;
3579 if (glyph == 0xffff)
3580 {
3581 hr = S_FALSE;
3582 glyph = 0x0;
3583 }
3584 pwOutGlyphs[i] = set_cache_glyph(psc, inChar, glyph);
3585 }
3586 }
3587
3588 return hr;
3589}
static WORD get_cache_glyph(SCRIPT_CACHE *psc, DWORD c)
Definition: usp10.c:825
static WORD set_cache_glyph(SCRIPT_CACHE *psc, WCHAR c, WORD glyph)
Definition: usp10.c:836
static WCHAR mirror_char(WCHAR ch)
Definition: usp10.c:940
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR int int WORD SCRIPT_CHARPROP WORD * pwOutGlyphs
Definition: usp10.c:64
#define SGCM_RTL
Definition: usp10.h:61
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define S_FALSE
Definition: winerror.h:2357
DWORD WINAPI GetGlyphIndicesW(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpstr, _In_ int c, _Out_writes_(c) LPWORD pgi, _In_ DWORD fl)
#define GGI_MARK_NONEXISTING_GLYPHS
Definition: wingdi.h:1085

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

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

4093{
4094 HRESULT hr;
4095 if (!pFeatureTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4096 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4097
4099}
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG tagScript
Definition: usp10.c:64
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int OPENTYPE_TAG * pFeatureTags
Definition: usp10.c:68
static SCRIPT_CACHE SCRIPT_ANALYSIS int cMaxTags
Definition: usp10.c:66
static SCRIPT_CACHE SCRIPT_ANALYSIS int OPENTYPE_TAG int * pcTags
Definition: usp10.c:66
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG tagLangSys
Definition: usp10.c:64
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:3523

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

4084{
4085 HRESULT hr;
4086 if (!pLangSysTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4087 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4088
4090}
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG int OPENTYPE_TAG * pLangSysTags
Definition: usp10.c:67
HRESULT SHAPE_GetFontLanguageTags(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, int cMaxTags, OPENTYPE_TAG *pLangSysTags, int *pcTags)
Definition: shape.c:3495

◆ ScriptGetFontProperties()

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

Definition at line 1176 of file usp10.c.

1177{
1178 HRESULT hr;
1179
1180 TRACE("%p,%p,%p\n", hdc, psc, sfp);
1181
1182 if (!sfp) return E_INVALIDARG;
1183 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
1184
1185 if (sfp->cBytes != sizeof(SCRIPT_FONTPROPERTIES))
1186 return E_INVALIDARG;
1187
1189
1190 return S_OK;
1191}
static void get_cache_font_properties(SCRIPT_FONTPROPERTIES *sfp, ScriptCache *sc)
Definition: usp10.c:810

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

4075{
4076 HRESULT hr;
4077 if (!pScriptTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4078 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4079
4081}
HRESULT SHAPE_GetFontScriptTags(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags)
Definition: shape.c:3477

◆ ScriptGetGlyphABCWidth()

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

Definition at line 3708 of file usp10.c.

3709{
3710 HRESULT hr;
3711
3712 TRACE("(%p, %p, 0x%04x, %p)\n", hdc, psc, glyph, abc);
3713
3714 if (!abc) return E_INVALIDARG;
3715 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3716
3717 if (!get_cache_glyph_widths(psc, glyph, abc))
3718 {
3719 if (!hdc) return E_PENDING;
3721 {
3722 if (!GetCharABCWidthsI(hdc, 0, 1, &glyph, abc)) return S_FALSE;
3723 }
3724 else
3725 {
3726 INT width;
3727 if (!GetCharWidthI(hdc, glyph, 1, NULL, &width)) return S_FALSE;
3728 abc->abcB = width;
3729 abc->abcA = abc->abcC = 0;
3730 }
3732 }
3733 return S_OK;
3734}
static BYTE get_cache_pitch_family(SCRIPT_CACHE *psc)
Definition: usp10.c:820
static BOOL set_cache_glyph_widths(SCRIPT_CACHE *psc, WORD glyph, ABC *abc)
Definition: usp10.c:857
static BOOL get_cache_glyph_widths(SCRIPT_CACHE *psc, WORD glyph, ABC *abc)
Definition: usp10.c:847
GLint GLint GLsizei width
Definition: gl.h:1546
int abcA
Definition: wingdi.h:1411
UINT abcB
Definition: wingdi.h:1412
int abcC
Definition: wingdi.h:1413
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 3998 of file usp10.c.

4001{
4002 int i, next = 0, direction;
4003
4004 TRACE("(%p, %d, %d, %p, %p, %p, %p)\n",
4005 sa, nbchars, nbglyphs, advances, log_clust, sva, widths);
4006
4007 if (sa->fRTL && !sa->fLogicalOrder)
4008 direction = -1;
4009 else
4010 direction = 1;
4011
4012 for (i = 0; i < nbchars; i++)
4013 {
4014 int clust_size = get_cluster_size(log_clust, nbchars, i, direction, NULL, NULL);
4015 int advance = get_glyph_cluster_advance(advances, sva, log_clust, nbglyphs, nbchars, log_clust[i], direction);
4016 int j;
4017
4018 for (j = 0; j < clust_size; j++)
4019 {
4020 widths[next] = advance / clust_size;
4021 next++;
4022 if (j) i++;
4023 }
4024 }
4025
4026 return S_OK;
4027}
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 1154 of file usp10.c.

1155{
1156 TRACE("(%p,%p)\n", props, num);
1157
1158 if (!props && !num) return E_INVALIDARG;
1159
1160 if (num) *num = ARRAY_SIZE(script_props);
1161 if (props) *props = script_props;
1162
1163 return S_OK;
1164}
static const SCRIPT_PROPERTIES * script_props[]
Definition: usp10.c:636
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 3074 of file usp10.c.

3075{
3076 enum usp10_script script;
3077 unsigned int i, consumed;
3078
3079 TRACE("(%s,%d,0x%x)\n", debugstr_wn(chars, len), len, flag);
3080
3081 if (!chars || len < 0)
3082 return E_INVALIDARG;
3083
3084 for (i = 0; i < len; i+=consumed)
3085 {
3086 if ((flag & SIC_ASCIIDIGIT) && chars[i] >= 0x30 && chars[i] <= 0x39)
3087 return S_OK;
3088
3089 script = get_char_script(chars,i,len, &consumed);
3090 if ((scriptInformation[script].props.fComplex && (flag & SIC_COMPLEX))||
3092 return S_OK;
3093 }
3094 return S_FALSE;
3095}
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 1853 of file usp10.c.

1856{
1858}
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:1344

Referenced by _test_items_ok(), 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 1828 of file usp10.c.

1831{
1833}

◆ ScriptJustify()

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

Definition at line 4063 of file usp10.c.

4065{
4066 int i;
4067
4068 FIXME("(%p, %p, %d, %d, %d, %p)\n", sva, advance, num_glyphs, dx, min_kashida, justify);
4069
4070 for (i = 0; i < num_glyphs; i++) justify[i] = advance[i];
4071 return S_OK;
4072}

◆ ScriptLayout()

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

Definition at line 3752 of file usp10.c.

3753{
3754 int* indexs;
3755 int ich;
3756
3757 TRACE("(%d, %p, %p, %p)\n", runs, level, vistolog, logtovis);
3758
3759 if (!level || (!vistolog && !logtovis))
3760 return E_INVALIDARG;
3761
3762 if (!(indexs = heap_calloc(runs, sizeof(*indexs))))
3763 return E_OUTOFMEMORY;
3764
3765 if (vistolog)
3766 {
3767 for( ich = 0; ich < runs; ich++)
3768 indexs[ich] = ich;
3769
3770 ich = 0;
3771 while (ich < runs)
3772 ich += BIDI_ReorderV2lLevel(0, indexs+ich, level+ich, runs - ich, FALSE);
3773 memcpy(vistolog, indexs, runs * sizeof(*vistolog));
3774 }
3775
3776 if (logtovis)
3777 {
3778 for( ich = 0; ich < runs; ich++)
3779 indexs[ich] = ich;
3780
3781 ich = 0;
3782 while (ich < runs)
3783 ich += BIDI_ReorderL2vLevel(0, indexs+ich, level+ich, runs - ich, FALSE);
3784 memcpy(logtovis, indexs, runs * sizeof(*logtovis));
3785 }
3786 heap_free(indexs);
3787
3788 return S_OK;
3789}
GLint level
Definition: gl.h:1546
int BIDI_ReorderL2vLevel(int level, int *pIndexs, const BYTE *plevel, int cch, BOOL fReverse)
Definition: bidi.c:1215
int BIDI_ReorderV2lLevel(int level, int *pIndexs, const BYTE *plevel, int cch, BOOL fReverse)
Definition: bidi.c:1188

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

3513{
3514 HRESULT hr;
3515 SCRIPT_GLYPHPROP *glyphProps;
3516 int i;
3517
3518 TRACE("(%p, %p, %p, %d, %p, %p, %p, %p, %p)\n", hdc, psc, pwGlyphs, cGlyphs, psva, psa,
3519 piAdvance, pGoffset, pABC);
3520
3521 if (!psva) return E_INVALIDARG;
3522 if (!pGoffset) return E_FAIL;
3523
3524 if (!(glyphProps = heap_calloc(cGlyphs, sizeof(*glyphProps))))
3525 return E_OUTOFMEMORY;
3526
3527 for (i = 0; i < cGlyphs; i++)
3528 glyphProps[i].sva = psva[i];
3529
3530 hr = ScriptPlaceOpenType(hdc, psc, psa, scriptInformation[psa->eScript].scriptTag, 0, NULL, NULL, 0, NULL, NULL, NULL, 0, pwGlyphs, glyphProps, cGlyphs, piAdvance, pGoffset, pABC);
3531
3532 heap_free(glyphProps);
3533
3534 return hr;
3535}
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:3387

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

3396{
3397 HRESULT hr;
3398 int i;
3399 static int once = 0;
3400
3401 TRACE("(%p, %p, %p, %s, %s, %p, %p, %d, %s, %p, %p, %d, %p, %p, %d, %p %p %p)\n",
3402 hdc, psc, psa,
3403 debugstr_an((char*)&tagScript,4), debugstr_an((char*)&tagLangSys,4),
3405 pwLogClust, pCharProps, cChars, pwGlyphs, pGlyphProps, cGlyphs, piAdvance,
3406 pGoffset, pABC);
3407
3408 if (!pGlyphProps) return E_INVALIDARG;
3409 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3410 if (!pGoffset) return E_FAIL;
3411
3412 if (cRanges)
3413 if (!once++) FIXME("Ranges not supported yet\n");
3414
3415 ((ScriptCache *)*psc)->userScript = tagScript;
3416 ((ScriptCache *)*psc)->userLang = tagLangSys;
3417
3418 if (pABC) memset(pABC, 0, sizeof(ABC));
3419 for (i = 0; i < cGlyphs; i++)
3420 {
3421 WORD glyph;
3422 ABC abc;
3423
3424 /* FIXME: set to more reasonable values */
3425 pGoffset[i].du = pGoffset[i].dv = 0;
3426
3427 if (pGlyphProps[i].sva.fZeroWidth)
3428 {
3429 abc.abcA = abc.abcB = abc.abcC = 0;
3430 if (piAdvance) piAdvance[i] = 0;
3431 continue;
3432 }
3433
3434 if (psa->fNoGlyphIndex)
3435 {
3436 if (FAILED(hr = ScriptGetCMap(hdc, psc, &pwGlyphs[i], 1, 0, &glyph))) return hr;
3437 }
3438 else
3439 {
3440 hr = S_OK;
3441 glyph = pwGlyphs[i];
3442 }
3443
3444 if (hr == S_FALSE)
3445 {
3446 if (!hdc) return E_PENDING;
3448 {
3449 if (!GetCharABCWidthsW(hdc, pwGlyphs[i], pwGlyphs[i], &abc)) return S_FALSE;
3450 }
3451 else
3452 {
3453 INT width;
3454 if (!GetCharWidthW(hdc, pwGlyphs[i], pwGlyphs[i], &width)) return S_FALSE;
3455 abc.abcB = width;
3456 abc.abcA = abc.abcC = 0;
3457 }
3458 }
3459 else if (!get_cache_glyph_widths(psc, glyph, &abc))
3460 {
3461 if (!hdc) return E_PENDING;
3463 {
3464 if (!GetCharABCWidthsI(hdc, glyph, 1, NULL, &abc)) return S_FALSE;
3465 }
3466 else
3467 {
3468 INT width;
3469 if (!GetCharWidthI(hdc, glyph, 1, NULL, &width)) return S_FALSE;
3470 abc.abcB = width;
3471 abc.abcA = abc.abcC = 0;
3472 }
3473 set_cache_glyph_widths(psc, glyph, &abc);
3474 }
3475 if (pABC)
3476 {
3477 pABC->abcA += abc.abcA;
3478 pABC->abcB += abc.abcB;
3479 pABC->abcC += abc.abcC;
3480 }
3481 if (piAdvance) piAdvance[i] = abc.abcA + abc.abcB + abc.abcC;
3482 }
3483
3484 SHAPE_ApplyOpenTypePositions(hdc, (ScriptCache *)*psc, psa, pwGlyphs, cGlyphs, piAdvance, pGoffset);
3485
3486 if (pABC) TRACE("Total for run: abcA=%d, abcB=%d, abcC=%d\n", pABC->abcA, pABC->abcB, pABC->abcC);
3487 return S_OK;
3488}
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define FAILED(hr)
Definition: intsafe.h:51
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int cRanges
Definition: usp10.c:64
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES ** rpRangeProperties
Definition: usp10.c:64
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int * rcRangeChars
Definition: usp10.c:64
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR * pwcChars
Definition: usp10.c:64
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR int int WORD SCRIPT_CHARPROP * pCharProps
Definition: usp10.c:64
void SHAPE_ApplyOpenTypePositions(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WORD *pwGlyphs, INT cGlyphs, int *piAdvance, GOFFSET *pGoffset)
Definition: shape.c:3429
LONG dv
Definition: usp10.h:201
LONG du
Definition: usp10.h:200
BOOL WINAPI GetCharWidthW(_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 1209 of file usp10.c.

1210{
1211 DWORD plgid, sub;
1212
1213 TRACE("0x%x, %p\n", locale, sds);
1214
1215 /* This implementation appears to be correct for all languages, but it's
1216 * not clear if sds->DigitSubstitute is ever set to anything except
1217 * CONTEXT or NONE in reality */
1218
1219 if (!sds) return E_POINTER;
1220
1222
1224 return E_INVALIDARG;
1225
1227 sds->TraditionalDigitLanguage = plgid;
1228
1229 if (plgid == LANG_ARABIC || plgid == LANG_FARSI)
1230 sds->NationalDigitLanguage = plgid;
1231 else
1233
1234 if (!GetLocaleInfoW(locale, LOCALE_IDIGITSUBSTITUTION | LOCALE_RETURN_NUMBER,
1235 (WCHAR *)&sub, sizeof(sub) / sizeof(WCHAR)))
1236 return E_INVALIDARG;
1237
1238 switch (sub)
1239 {
1240 case 0:
1241 if (plgid == LANG_ARABIC || plgid == LANG_FARSI)
1243 else
1245 break;
1246 case 1:
1248 break;
1249 case 2:
1251 break;
1252 default:
1254 break;
1255 }
1256
1257 sds->dwReserved = 0;
1258 return S_OK;
1259}
Definition: _locale.h:75
BOOL WINAPI IsValidLocale(LCID lcid, DWORD flags)
Definition: lang.c:1558
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:1108
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: lang.c:1512
#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:201

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

3325{
3326 HRESULT hr;
3327 int i;
3328 SCRIPT_CHARPROP *charProps;
3329 SCRIPT_GLYPHPROP *glyphProps;
3330
3331 if (!psva || !pcGlyphs) return E_INVALIDARG;
3332 if (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
3333
3334 if (!(charProps = heap_calloc(cChars, sizeof(*charProps))))
3335 return E_OUTOFMEMORY;
3336
3337 if (!(glyphProps = heap_calloc(cMaxGlyphs, sizeof(*glyphProps))))
3338 {
3339 heap_free(charProps);
3340 return E_OUTOFMEMORY;
3341 }
3342
3344
3345 if (SUCCEEDED(hr))
3346 {
3347 for (i = 0; i < *pcGlyphs; i++)
3348 psva[i] = glyphProps[i].sva;
3349 }
3350
3351 heap_free(charProps);
3352 heap_free(glyphProps);
3353
3354 return hr;
3355}
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:3124
#define SUCCEEDED(hr)
Definition: intsafe.h:50
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR int int WORD SCRIPT_CHARPROP WORD SCRIPT_GLYPHPROP int * pcGlyphs
Definition: usp10.c:64
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR int int cMaxGlyphs
Definition: usp10.c:64

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

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

Referenced by ScriptShape().

◆ ScriptString_pcOutChars()

const int *WINAPI ScriptString_pcOutChars ( SCRIPT_STRING_ANALYSIS  ssa)

Definition at line 3938 of file usp10.c.

3939{
3940 StringAnalysis *analysis = ssa;
3941
3942 TRACE("(%p)\n", ssa);
3943
3944 if (!analysis) return NULL;
3945 return &analysis->clip_len;
3946}
int clip_len
Definition: usp10.c:714

Referenced by EDIT_BuildLineDefs_ML(), and test_ScriptString().

◆ ScriptString_pLogAttr()

const SCRIPT_LOGATTR *WINAPI ScriptString_pLogAttr ( SCRIPT_STRING_ANALYSIS  ssa)

Definition at line 3915 of file usp10.c.

3916{
3917 StringAnalysis *analysis = ssa;
3918
3919 TRACE("(%p)\n", ssa);
3920
3921 if (!analysis) return NULL;
3922 if (!(analysis->ssa_flags & SSA_BREAK)) return NULL;
3923 return analysis->logattrs;
3924}
DWORD ssa_flags
Definition: usp10.c:712
SCRIPT_LOGATTR * logattrs
Definition: usp10.c:720
#define SSA_BREAK
Definition: usp10.h:39

◆ ScriptString_pSize()

const SIZE *WINAPI ScriptString_pSize ( SCRIPT_STRING_ANALYSIS  ssa)

Definition at line 3876 of file usp10.c.

3877{
3878 int i, j;
3879 StringAnalysis *analysis = ssa;
3880
3881 TRACE("(%p)\n", ssa);
3882
3883 if (!analysis) return NULL;
3884 if (!(analysis->ssa_flags & SSA_GLYPHS)) return NULL;
3885
3886 if (!(analysis->flags & SCRIPT_STRING_ANALYSIS_FLAGS_SIZE))
3887 {
3888 analysis->sz.cy = analysis->glyphs[0].sc->tm.tmHeight;
3889
3890 analysis->sz.cx = 0;
3891 for (i = 0; i < analysis->numItems; i++)
3892 {
3893 if (analysis->glyphs[i].sc->tm.tmHeight > analysis->sz.cy)
3894 analysis->sz.cy = analysis->glyphs[i].sc->tm.tmHeight;
3895 for (j = 0; j < analysis->glyphs[i].numGlyphs; j++)
3896 analysis->sz.cx += analysis->glyphs[i].piAdvance[j];
3897 }
3899 }
3900 return &analysis->sz;
3901}
StringGlyphs * glyphs
Definition: usp10.c:719
DWORD flags
Definition: usp10.c:713
int numItems
Definition: usp10.c:718
ScriptCache * sc
Definition: usp10.c:692
int * piAdvance
Definition: usp10.c:696
int numGlyphs
Definition: usp10.c:693
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
LONG tmHeight
Definition: wingdi.h:2383
#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 1985 of file usp10.c.

1991{
1993 StringAnalysis *analysis = NULL;
1994 SCRIPT_CONTROL sControl;
1995 SCRIPT_STATE sState;
1996 int i, num_items = 255;
1997 BYTE *BidiLevel;
1998 WCHAR *iString = NULL;
1999
2000 TRACE("(%p,%p,%d,%d,%d,0x%x,%d,%p,%p,%p,%p,%p,%p)\n",
2001 hdc, pString, cString, cGlyphs, iCharset, dwFlags, iReqWidth,
2002 psControl, psState, piDx, pTabdef, pbInClass, pssa);
2003
2004 if (iCharset != -1)
2005 {
2006 FIXME("Only Unicode strings are supported\n");
2007 return E_INVALIDARG;
2008 }
2009 if (cString < 1 || !pString) return E_INVALIDARG;
2010 if ((dwFlags & SSA_GLYPHS) && !hdc) return E_PENDING;
2011
2012 if (!(analysis = heap_alloc_zero(sizeof(*analysis))))
2013 return E_OUTOFMEMORY;
2014 if (!(analysis->pItem = heap_calloc(num_items + 1, sizeof(*analysis->pItem))))
2015 goto error;
2016
2017 /* FIXME: handle clipping */
2018 analysis->clip_len = cString;
2019 analysis->hdc = hdc;
2020 analysis->ssa_flags = dwFlags;
2021
2022 if (psState)
2023 sState = *psState;
2024 else
2025 memset(&sState, 0, sizeof(SCRIPT_STATE));
2026
2027 if (psControl)
2028 sControl = *psControl;
2029 else
2030 memset(&sControl, 0, sizeof(SCRIPT_CONTROL));
2031
2032 if (dwFlags & SSA_PASSWORD)
2033 {
2034 if (!(iString = heap_calloc(cString, sizeof(*iString))))
2035 {
2036 hr = E_OUTOFMEMORY;
2037 goto error;
2038 }
2039 for (i = 0; i < cString; i++)
2040 iString[i] = *((const WCHAR *)pString);
2041 pString = iString;
2042 }
2043
2044 hr = ScriptItemize(pString, cString, num_items, &sControl, &sState, analysis->pItem,
2045 &analysis->numItems);
2046
2047 if (FAILED(hr))
2048 {
2049 if (hr == E_OUTOFMEMORY)
2050 hr = E_INVALIDARG;
2051 goto error;
2052 }
2053
2054 /* set back to out of memory for default goto error behaviour */
2055 hr = E_OUTOFMEMORY;
2056
2057 if (dwFlags & SSA_BREAK)
2058 {
2059 if (!(analysis->logattrs = heap_calloc(cString, sizeof(*analysis->logattrs))))
2060 goto error;
2061
2062 for (i = 0; i < analysis->numItems; ++i)
2063 ScriptBreak(&((const WCHAR *)pString)[analysis->pItem[i].iCharPos],
2064 analysis->pItem[i + 1].iCharPos - analysis->pItem[i].iCharPos,
2065 &analysis->pItem[i].a, &analysis->logattrs[analysis->pItem[i].iCharPos]);
2066 }
2067
2068 if (!(analysis->logical2visual = heap_calloc(analysis->numItems, sizeof(*analysis->logical2visual))))
2069 goto error;
2070 if (!(BidiLevel = heap_alloc_zero(analysis->numItems)))
2071 goto error;
2072
2073 if (dwFlags & SSA_GLYPHS)
2074 {
2075 int tab_x = 0;
2076
2077 if (!(analysis->glyphs = heap_calloc(analysis->numItems, sizeof(*analysis->glyphs))))
2078 {
2079 heap_free(BidiLevel);
2080 goto error;
2081 }
2082
2083 for (i = 0; i < analysis->numItems; i++)
2084 {
2085 SCRIPT_CACHE *sc = (SCRIPT_CACHE*)&analysis->glyphs[i].sc;
2086 int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
2087 int numGlyphs = 1.5 * cChar + 16;
2088 WORD *glyphs = heap_calloc(numGlyphs, sizeof(*glyphs));
2089 WORD *pwLogClust = heap_calloc(cChar, sizeof(*pwLogClust));
2090 int *piAdvance = heap_calloc(numGlyphs, sizeof(*piAdvance));
2091 SCRIPT_VISATTR *psva = heap_calloc(numGlyphs, sizeof(*psva));
2092 GOFFSET *pGoffset = heap_calloc(numGlyphs, sizeof(*pGoffset));
2093 int numGlyphsReturned;
2094 HFONT originalFont = 0x0;
2095
2096 /* FIXME: non unicode strings */
2097 const WCHAR* pStr = (const WCHAR*)pString;
2098 analysis->glyphs[i].fallbackFont = NULL;
2099
2100 if (!glyphs || !pwLogClust || !piAdvance || !psva || !pGoffset)
2101 {
2102 heap_free (BidiLevel);
2103 heap_free (glyphs);
2105 heap_free (piAdvance);
2106 heap_free (psva);
2107 heap_free (pGoffset);
2108 hr = E_OUTOFMEMORY;
2109 goto error;
2110 }
2111
2112 if ((dwFlags & SSA_FALLBACK) && requires_fallback(hdc, sc, &analysis->pItem[i].a, &pStr[analysis->pItem[i].iCharPos], cChar))
2113 {
2114 LOGFONTW lf;
2115 GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), & lf);
2117 lf.lfFaceName[0] = 0;
2118 find_fallback_font(analysis->pItem[i].a.eScript, lf.lfFaceName);
2119 if (lf.lfFaceName[0])
2120 {
2121 analysis->glyphs[i].fallbackFont = CreateFontIndirectW(&lf);
2122 if (analysis->glyphs[i].fallbackFont)
2123 {
2124 ScriptFreeCache(sc);
2125 originalFont = SelectObject(hdc, analysis->glyphs[i].fallbackFont);
2126 }
2127 }
2128 }
2129
2130 /* FIXME: When we properly shape Hangul remove this check */
2131 if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && analysis->pItem[i].a.eScript == Script_Hangul)
2132 analysis->pItem[i].a.fNoGlyphIndex = TRUE;
2133
2134 if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && !scriptInformation[analysis->pItem[i].a.eScript].props.fComplex && !analysis->pItem[i].a.fRTL)
2135 analysis->pItem[i].a.fNoGlyphIndex = TRUE;
2136
2137 ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos], cChar, numGlyphs,
2138 &analysis->pItem[i].a, glyphs, pwLogClust, psva, &numGlyphsReturned);
2139 hr = ScriptPlace(hdc, sc, glyphs, numGlyphsReturned, psva, &analysis->pItem[i].a,
2140 piAdvance, pGoffset, &analysis->glyphs[i].abc);
2141 if (originalFont)
2142 SelectObject(hdc,originalFont);
2143
2144 if (dwFlags & SSA_TAB)
2145 {
2146 int tabi = 0;
2147 for (tabi = 0; tabi < cChar; tabi++)
2148 {
2149 if (pStr[analysis->pItem[i].iCharPos+tabi] == 0x0009)
2150 piAdvance[tabi] = getGivenTabWidth(analysis->glyphs[i].sc, pTabdef, analysis->pItem[i].iCharPos+tabi, tab_x);
2151 tab_x+=piAdvance[tabi];
2152 }
2153 }
2154
2155 analysis->glyphs[i].numGlyphs = numGlyphsReturned;
2156 analysis->glyphs[i].glyphs = glyphs;
2157 analysis->glyphs[i].pwLogClust = pwLogClust;
2158 analysis->glyphs[i].piAdvance = piAdvance;
2159 analysis->glyphs[i].psva = psva;
2160 analysis->glyphs[i].pGoffset = pGoffset;
2161 analysis->glyphs[i].iMaxPosX= -1;
2162
2163 BidiLevel[i] = analysis->pItem[i].a.s.uBidiLevel;
2164 }
2165 }
2166 else
2167 {
2168 for (i = 0; i < analysis->numItems; i++)
2169 BidiLevel[i] = analysis->pItem[i].a.s.uBidiLevel;
2170 }
2171
2172 ScriptLayout(analysis->numItems, BidiLevel, NULL, analysis->logical2visual);
2173 heap_free(BidiLevel);
2174
2175 *pssa = analysis;
2176 heap_free(iString);
2177 return S_OK;
2178
2179error:
2180 heap_free(iString);
2181 heap_free(analysis->glyphs);
2182 heap_free(analysis->logattrs);
2183 heap_free(analysis->pItem);
2184 heap_free(analysis->logical2visual);
2185 heap_free(analysis);
2186 return hr;
2187}
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:3510
static int getGivenTabWidth(ScriptCache *psc, SCRIPT_TABDEF *pTabdef, int charPos, int current_x)
Definition: usp10.c:1860
HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc)
Definition: usp10.c:1080
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:1853
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:3321
HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *logtovis)
Definition: usp10.c:3752
static BOOL requires_fallback(HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, const WCHAR *pwcInChars, int cChars)
Definition: usp10.c:1934
static void find_fallback_font(enum usp10_script scriptid, WCHAR *FaceName)
Definition: usp10.c:1961
HRESULT WINAPI ScriptBreak(const WCHAR *chars, int count, const SCRIPT_ANALYSIS *sa, SCRIPT_LOGATTR *la)
Definition: usp10.c:3047
FxString * pString
GLenum const GLvoid GLbitfield GLsizei numGlyphs
Definition: glext.h:11715
#define error(str)
Definition: mkdosfs.c:1605
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
BYTE lfCharSet
Definition: dimm.idl:67
DWORD bCharSet
Definition: usp10.h:112
int * logical2visual
Definition: usp10.c:722
SCRIPT_ITEM * pItem
Definition: usp10.c:717
SCRIPT_VISATTR * psva
Definition: usp10.c:697
int iMaxPosX
Definition: usp10.c:700
WORD * pwLogClust
Definition: usp10.c:695
HFONT fallbackFont
Definition: usp10.c:701
WORD * glyphs
Definition: usp10.c:694
ABC abc
Definition: usp10.c:699
GOFFSET * pGoffset
Definition: usp10.c:698
SCRIPT_STATE s
Definition: usp10.h:146
WORD fNoGlyphIndex
Definition: usp10.h:145
SCRIPT_ANALYSIS a
Definition: usp10.h:151
int iCharPos
Definition: usp10.h:150
WORD uBidiLevel
Definition: usp10.h:125
#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
@ Script_Hangul
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
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 2411 of file usp10.c.

2412{
2413 int item;
2414 int runningX = 0;
2415 StringAnalysis* analysis = ssa;
2416
2417 TRACE("(%p), %d, %d, (%p)\n", ssa, icp, fTrailing, pX);
2418
2419 if (!ssa || !pX) return S_FALSE;
2420 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
2421
2422 /* icp out of range */
2423 if(icp < 0)
2424 {
2426 return E_INVALIDARG;
2427 }
2428
2429 for(item=0; item<analysis->numItems; item++)
2430 {
2431 int CP, i;
2432 int offset;
2433
2434 i = analysis->logical2visual[item];
2435 CP = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
2436 /* initialize max extents for uninitialized runs */
2437 if (analysis->glyphs[i].iMaxPosX == -1)
2438 {
2439 if (analysis->pItem[i].a.fRTL)
2440 ScriptCPtoX(0, FALSE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2441 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2442 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2443 else
2444 ScriptCPtoX(CP, TRUE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2445 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2446 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2447 }
2448
2449 if (icp >= analysis->pItem[i+1].iCharPos || icp < analysis->pItem[i].iCharPos)
2450 {
2451 runningX += analysis->glyphs[i].iMaxPosX;
2452 continue;
2453 }
2454
2455 icp -= analysis->pItem[i].iCharPos;
2456 ScriptCPtoX(icp, fTrailing, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2457 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2458 &analysis->pItem[i].a, &offset);
2459 runningX += offset;
2460
2461 *pX = runningX;
2462 return S_OK;
2463 }
2464
2465 /* icp out of range */
2467 return E_INVALIDARG;
2468}
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:2650
#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 2556 of file usp10.c.

2557{
2558 StringAnalysis* analysis;
2559 BOOL invalid;
2560 int i;
2561
2562 TRACE("(%p)\n", pssa);
2563
2564 if (!pssa || !(analysis = *pssa)) return E_INVALIDARG;
2565
2567
2568 if (analysis->glyphs)
2569 {
2570 for (i = 0; i < analysis->numItems; i++)
2571 {
2572 heap_free(analysis->glyphs[i].glyphs);
2573 heap_free(analysis->glyphs[i].pwLogClust);
2574 heap_free(analysis->glyphs[i].piAdvance);
2575 heap_free(analysis->glyphs[i].psva);
2576 heap_free(analysis->glyphs[i].pGoffset);
2577 if (analysis->glyphs[i].fallbackFont)
2578 DeleteObject(analysis->glyphs[i].fallbackFont);
2579 ScriptFreeCache((SCRIPT_CACHE *)&analysis->glyphs[i].sc);
2580 heap_free(analysis->glyphs[i].sc);
2581 }
2582 heap_free(analysis->glyphs);
2583 }
2584
2585 heap_free(analysis->pItem);
2586 heap_free(analysis->logattrs);
2587 heap_free(analysis->logical2visual);
2588 heap_free(analysis);
2589
2590 if (invalid) return E_INVALIDARG;
2591 return S_OK;
2592}
pKey DeleteObject()
static const WCHAR invalid[]
Definition: assoc.c:39

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

3805{
3806 int i, j, next = 0;
3807 StringAnalysis *analysis = ssa;
3808
3809 TRACE("%p, %p\n", ssa, piDx);
3810
3811 if (!analysis) return S_FALSE;
3812 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
3813
3814 for (i = 0; i < analysis->numItems; i++)
3815 {
3816 int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
3817 int direction = 1;
3818
3819 if (analysis->pItem[i].a.fRTL && ! analysis->pItem[i].a.fLogicalOrder)
3820 direction = -1;
3821
3822 for (j = 0; j < cChar; j++)
3823 {
3824 int k;
3825 int glyph = analysis->glyphs[i].pwLogClust[j];
3826 int clust_size = get_cluster_size(analysis->glyphs[i].pwLogClust,
3827 cChar, j, direction, NULL, NULL);
3828 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);
3829
3830 for (k = 0; k < clust_size; k++)
3831 {
3832 piDx[next] = advance / clust_size;
3833 next++;
3834 if (k) j++;
3835 }
3836 }
3837 }
3838 return S_OK;
3839}
WORD fLogicalOrder
Definition: usp10.h:144

Referenced by EDIT_BuildLineDefs_ML(), and LpkGetTextExtentExPoint().

◆ ScriptStringGetOrder()

HRESULT WINAPI ScriptStringGetOrder ( SCRIPT_STRING_ANALYSIS  ssa,
UINT order 
)

Definition at line 3961 of file usp10.c.

3962{
3963 int i, j;
3964 unsigned int k;
3965 StringAnalysis *analysis = ssa;
3966
3967 TRACE("(%p)\n", ssa);
3968
3969 if (!analysis) return S_FALSE;
3970 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
3971
3972 /* FIXME: handle RTL scripts */
3973 for (i = 0, k = 0; i < analysis->numItems; i++)
3974 for (j = 0; j < analysis->glyphs[i].numGlyphs; j++, k++)
3975 order[k] = k;
3976
3977 return S_OK;
3978}
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 2366 of file usp10.c.

2374{
2375 StringAnalysis *analysis;
2376 int item;
2377 HRESULT hr;
2378
2379 TRACE("(%p,%d,%d,0x%08x,%s,%d,%d,%d)\n",
2380 ssa, iX, iY, uOptions, wine_dbgstr_rect(prc), iMinSel, iMaxSel, fDisabled);
2381
2382 if (!(analysis = ssa)) return E_INVALIDARG;
2383 if (!(analysis->ssa_flags & SSA_GLYPHS)) return E_INVALIDARG;
2384
2385 for (item = 0; item < analysis->numItems; item++)
2386 {
2387 hr = SS_ItemOut( ssa, iX, iY, analysis->logical2visual[item], -1, -1, uOptions, prc, FALSE, fDisabled);
2388 if (FAILED(hr))
2389 return hr;
2390 }
2391
2392 if (iMinSel < iMaxSel && (iMinSel > 0 || iMaxSel > 0))
2393 {
2394 if (iMaxSel > 0 && iMinSel < 0)
2395 iMinSel = 0;
2396 for (item = 0; item < analysis->numItems; item++)
2397 {
2398 hr = SS_ItemOut( ssa, iX, iY, analysis->logical2visual[item], iMinSel, iMaxSel, uOptions, prc, TRUE, fDisabled);
2399 if (FAILED(hr))
2400 return hr;
2401 }
2402 }
2403
2404 return S_OK;
2405}
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:2200
_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 3854 of file usp10.c.

3855{
3856 StringAnalysis *analysis = ssa;
3857
3858 TRACE("(%p)\n", ssa);
3859
3860 if (!analysis) return E_INVALIDARG;
3862}

◆ ScriptStringXtoCP()

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

Definition at line 2474 of file usp10.c.

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

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

3599{
3600 HRESULT hr = S_OK;
3601 INT i, dir = 1;
3602 INT *lpDx;
3603 WORD *reordered_glyphs = (WORD *)pwGlyphs;
3604
3605 TRACE("(%p, %p, %d, %d, %08x, %s, %p, %p, %d, %p, %d, %p, %p, %p)\n",
3606 hdc, psc, x, y, fuOptions, wine_dbgstr_rect(lprc), psa, pwcReserved, iReserved, pwGlyphs, cGlyphs,
3607 piAdvance, piJustify, pGoffset);
3608
3609 if (!hdc || !psc) return E_INVALIDARG;
3610 if (!piAdvance || !psa || !pwGlyphs) return E_INVALIDARG;
3611
3612 fuOptions &= ETO_CLIPPED + ETO_OPAQUE;
3613 fuOptions |= ETO_IGNORELANGUAGE;
3614 if (!psa->fNoGlyphIndex) /* Have Glyphs? */
3615 fuOptions |= ETO_GLYPH_INDEX; /* Say don't do translation to glyph */
3616
3617 if (!(lpDx = heap_calloc(cGlyphs, 2 * sizeof(*lpDx))))
3618 return E_OUTOFMEMORY;
3619 fuOptions |= ETO_PDY;
3620
3621 if (psa->fRTL && psa->fLogicalOrder)
3622 {
3623 if (!(reordered_glyphs = heap_calloc(cGlyphs, sizeof(*reordered_glyphs))))
3624 {
3625 heap_free( lpDx );
3626 return E_OUTOFMEMORY;
3627 }
3628
3629 for (i = 0; i < cGlyphs; i++)
3630 reordered_glyphs[i] = pwGlyphs[cGlyphs - 1 - i];
3631 dir = -1;
3632 }
3633
3634 for (i = 0; i < cGlyphs; i++)
3635 {
3636 int orig_index = (dir > 0) ? i : cGlyphs - 1 - i;
3637 lpDx[i * 2] = piAdvance[orig_index];
3638 lpDx[i * 2 + 1] = 0;
3639
3640 if (pGoffset)
3641 {
3642 if (i == 0)
3643 {
3644 x += pGoffset[orig_index].du * dir;
3645 y += pGoffset[orig_index].dv;
3646 }
3647 else
3648 {
3649 lpDx[(i - 1) * 2] += pGoffset[orig_index].du * dir;
3650 lpDx[(i - 1) * 2 + 1] += pGoffset[orig_index].dv;
3651 }
3652 lpDx[i * 2] -= pGoffset[orig_index].du * dir;
3653 lpDx[i * 2 + 1] -= pGoffset[orig_index].dv;
3654 }
3655 }
3656
3657 if (!ExtTextOutW(hdc, x, y, fuOptions, lprc, reordered_glyphs, cGlyphs, lpDx))
3658 hr = S_FALSE;
3659
3660 if (reordered_glyphs != pwGlyphs) heap_free( reordered_glyphs );
3661 heap_free(lpDx);
3662
3663 return hr;
3664}
unsigned int dir
Definition: maze.c:112
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#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
_In_ int _Inout_ LPRECT lprc
Definition: winuser.h:4466

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

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

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

762{
763 sc->sfp.cBytes = sizeof(sc->sfp);
764
765 if (!sc->sfnt)
766 {
767 sc->sfp.wgBlank = sc->tm.tmBreakChar;
768 sc->sfp.wgDefault = sc->tm.tmDefaultChar;
769 sc->sfp.wgInvalid = sc->sfp.wgBlank;
770 sc->sfp.wgKashida = 0xFFFF;
771 sc->sfp.iKashidaWidth = 0;
772 }
773 else
774 {
775 static const WCHAR chars[4] = {0x0020, 0x200B, 0xF71B, 0x0640};
776 /* U+0020: numeric space
777 U+200B: zero width space
778 U+F71B: unknown char found by black box testing
779 U+0640: kashida */
780 WORD gi[4];
781
783 {
784 if(gi[0] != 0xFFFF) /* 0xFFFF: index of default non exist char */
785 sc->sfp.wgBlank = gi[0];
786 else
787 sc->sfp.wgBlank = 0;
788
789 sc->sfp.wgDefault = 0;
790
791 if (gi[2] != 0xFFFF)
792 sc->sfp.wgInvalid = gi[2];
793 else if (gi[1] != 0xFFFF)
794 sc->sfp.wgInvalid = gi[1];
795 else if (gi[0] != 0xFFFF)
796 sc->sfp.wgInvalid = gi[0];
797 else
798 sc->sfp.wgInvalid = 0;
799
800 sc->sfp.wgKashida = gi[3];
801
802 sc->sfp.iKashidaWidth = 0; /* TODO */
803 }
804 else
805 return FALSE;
806 }
807 return TRUE;
808}
WCHAR tmBreakChar
Definition: wingdi.h:2397
WCHAR tmDefaultChar
Definition: wingdi.h:2396

Referenced by init_script_cache().

◆ set_cache_glyph()

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

Definition at line 836 of file usp10.c.

837{
838 CacheGlyphPage **page = &((ScriptCache *)*psc)->page[c / 0x10000];
839 WORD **block;
840 if (!*page && !(*page = heap_alloc_zero(sizeof(CacheGlyphPage)))) return 0;
841
842 block = &(*page)->glyphs[(c % 0x10000) >> GLYPH_BLOCK_SHIFT];
843 if (!*block && !(*block = heap_alloc_zero(sizeof(WORD) * GLYPH_BLOCK_SIZE))) return 0;
844 return ((*block)[(c % 0x10000) & GLYPH_BLOCK_MASK] = glyph);
845}

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

858{
859 ABC **block = &((ScriptCache *)*psc)->widths[glyph >> GLYPH_BLOCK_SHIFT];
860
861 if (!*block && !(*block = heap_alloc_zero(sizeof(ABC) * GLYPH_BLOCK_SIZE))) return FALSE;
862 memcpy(&(*block)[glyph & GLYPH_BLOCK_MASK], abc, sizeof(ABC));
863 return TRUE;
864}

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

2210{
2211 StringAnalysis *analysis;
2212 int off_x = 0;
2213 HRESULT hr;
2214 COLORREF BkColor = 0x0;
2215 COLORREF TextColor = 0x0;
2216 INT BkMode = 0;
2217 INT runStart, runEnd;
2218 INT iGlyph, cGlyphs;
2219 HFONT oldFont = 0x0;
2220 RECT crc;
2221 int i;
2222
2223 TRACE("(%p,%d,%d,%d,%d,%d, 0x%1x, %d, %d)\n",
2224 ssa, iX, iY, iItem, cStart, cEnd, uOptions, fSelected, fDisabled);
2225
2226 if (!(analysis = ssa)) return E_INVALIDARG;
2227
2228 if ((cStart >= 0 && analysis->pItem[iItem+1].iCharPos <= cStart) ||
2229 (cEnd >= 0 && analysis->pItem[iItem].iCharPos >= cEnd))
2230 return S_OK;
2231
2232 CopyRect(&crc,prc);
2233 if (fSelected)
2234 {
2235 BkMode = GetBkMode(analysis->hdc);
2236 SetBkMode( analysis->hdc, OPAQUE);
2237 BkColor = GetBkColor(analysis->hdc);
2239 if (!fDisabled)
2240 {
2241 TextColor = GetTextColor(analysis->hdc);
2243 }
2244 }
2245 if (analysis->glyphs[iItem].fallbackFont)
2246 oldFont = SelectObject(analysis->hdc, analysis->glyphs[iItem].fallbackFont);
2247
2248 if (cStart >= 0 && analysis->pItem[iItem+1].iCharPos > cStart && analysis->pItem[iItem].iCharPos <= cStart)
2249 runStart = cStart - analysis->pItem[iItem].iCharPos;
2250 else
2251 runStart = 0;
2252 if (cEnd >= 0 && analysis->pItem[iItem+1].iCharPos > cEnd && analysis->pItem[iItem].iCharPos <= cEnd)
2253 runEnd = (cEnd-1) - analysis->pItem[iItem].iCharPos;
2254 else
2255 runEnd = (analysis->pItem[iItem+1].iCharPos - analysis->pItem[iItem].iCharPos) - 1;
2256
2257 if (analysis->pItem[iItem].a.fRTL)
2258 {
2259 if (cEnd >= 0 && cEnd < analysis->pItem[iItem+1].iCharPos)
2260 ScriptStringCPtoX(ssa, cEnd, FALSE, &off_x);
2261 else
2262 ScriptStringCPtoX(ssa, analysis->pItem[iItem+1].iCharPos-1, TRUE, &off_x);
2263 crc.left = iX + off_x;
2264 }
2265 else
2266 {
2267 if (cStart >=0 && runStart)
2268 ScriptStringCPtoX(ssa, cStart, FALSE, &off_x);
2269 else
2270 ScriptStringCPtoX(ssa, analysis->pItem[iItem].iCharPos, FALSE, &off_x);
2271 crc.left = iX + off_x;
2272 }
2273
2274 if (analysis->pItem[iItem].a.fRTL)
2275 iGlyph = analysis->glyphs[iItem].pwLogClust[runEnd];
2276 else
2277 iGlyph = analysis->glyphs[iItem].pwLogClust[runStart];
2278
2279 if (analysis->pItem[iItem].a.fRTL)
2280 cGlyphs = analysis->glyphs[iItem].pwLogClust[runStart] - iGlyph;
2281 else
2282 cGlyphs = analysis->glyphs[iItem].pwLogClust[runEnd] - iGlyph;
2283
2284 cGlyphs++;
2285
2286 /* adjust for cluster glyphs when starting */
2287 if (analysis->pItem[iItem].a.fRTL)
2288 i = analysis->pItem[iItem+1].iCharPos - 1;
2289 else
2290 i = analysis->pItem[iItem].iCharPos;
2291
2292 for (; i >=analysis->pItem[iItem].iCharPos && i < analysis->pItem[iItem+1].iCharPos; (analysis->pItem[iItem].a.fRTL)?i--:i++)
2293 {
2294 if (analysis->glyphs[iItem].pwLogClust[i - analysis->pItem[iItem].iCharPos] == iGlyph)
2295 {
2296 if (analysis->pItem[iItem].a.fRTL)
2297 ScriptStringCPtoX(ssa, i, TRUE, &off_x);
2298 else
2299 ScriptStringCPtoX(ssa, i, FALSE, &off_x);
2300 break;
2301 }
2302 }
2303
2304 if (cEnd < 0 || scriptInformation[analysis->pItem[iItem].a.eScript].props.fNeedsCaretInfo)
2305 {
2306 INT direction;
2307 INT clust_glyph;
2308
2309 clust_glyph = iGlyph + cGlyphs;
2310 if (analysis->pItem[iItem].a.fRTL)
2311 direction = -1;
2312 else
2313 direction = 1;
2314
2315 while(clust_glyph < analysis->glyphs[iItem].numGlyphs &&
2316 !does_glyph_start_cluster(analysis->glyphs[iItem].psva, analysis->glyphs[iItem].pwLogClust, (analysis->pItem[iItem+1].iCharPos - analysis->pItem[iItem].iCharPos), clust_glyph, direction))
2317 {
2318 cGlyphs++;
2319 clust_glyph++;
2320 }
2321 }
2322
2323 hr = ScriptTextOut(analysis->hdc,
2324 (SCRIPT_CACHE *)&analysis->glyphs[iItem].sc, iX + off_x,
2325 iY, uOptions, &crc, &analysis->pItem[iItem].a, NULL, 0,
2326 &analysis->glyphs[iItem].glyphs[iGlyph], cGlyphs,
2327 &analysis->glyphs[iItem].piAdvance[iGlyph], NULL,
2328 &analysis->glyphs[iItem].pGoffset[iGlyph]);
2329
2330 TRACE("ScriptTextOut hr=%08x\n", hr);
2331
2332 if (fSelected)
2333 {
2334 SetBkColor(analysis->hdc, BkColor);
2335 SetBkMode( analysis->hdc, BkMode);
2336 if (!fDisabled)
2337 SetTextColor(analysis->hdc, TextColor);
2338 }
2339 if (analysis->glyphs[iItem].fallbackFont)
2340 SelectObject(analysis->hdc, oldFont);
2341
2342 return hr;
2343}
HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrailing, int *pX)
Definition: usp10.c:2411
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:3595
LONG left
Definition: windef.h:306
DWORD COLORREF
Definition: windef.h:300
int WINAPI GetBkMode(_In_ HDC)
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
COLORREF WINAPI GetTextColor(_In_ HDC)
Definition: text.c:861
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:918
DWORD WINAPI GetSysColor(_In_ int)
BOOL WINAPI CopyRect(_Out_ LPRECT, _In_ LPCRECT)
#define COLOR_HIGHLIGHT
Definition: winuser.h:926
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:927

Referenced by ScriptStringOut().

◆ usp10_array_reserve()

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

Definition at line 730 of file usp10.c.

731{
732 SIZE_T max_capacity, new_capacity;
733 void *new_elements;
734
735 if (count <= *capacity)
736 return TRUE;
737
738 max_capacity = ~(SIZE_T)0 / size;
739 if (count > max_capacity)
740 return FALSE;
741
742 new_capacity = max(1, *capacity);
743 while (new_capacity < count && new_capacity <= max_capacity / 2)
744 new_capacity *= 2;
745 if (new_capacity < count)
746 new_capacity = count;
747
748 if (!*elements)
749 new_elements = heap_alloc_zero(new_capacity * size);
750 else
751 new_elements = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *elements, new_capacity * size);
752 if (!new_elements)
753 return FALSE;
754
755 *elements = new_elements;
756 *capacity = new_capacity;
757 return TRUE;
758}
#define GetProcessHeap()
Definition: compat.h:736
#define HeapReAlloc
Definition: compat.h:734
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#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 957 of file usp10.c.

958{
959 const struct usp10_script_range *range = value;
960 const DWORD *ch = key;
961
962 if (*ch < range->rangeFirst)
963 return -1;
964 if (*ch > range->rangeLast)
965 return 1;
966 return 0;
967}
Definition: copy.c:22
DWORD rangeFirst
Definition: usp10.c:52

Referenced by get_char_script().

◆ USP10_FindGlyphInLogClust()

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

Definition at line 1044 of file usp10.c.

1045{
1046 FindGlyph_struct fgs;
1047 WORD *ptr;
1048 INT k;
1049
1050 if (pwLogClust[0] < pwLogClust[cChars-1])
1051 fgs.ascending = TRUE;
1052 else
1053 fgs.ascending = FALSE;
1054
1055 fgs.target = target;
1056 ptr = bsearch(&fgs, pwLogClust, cChars, sizeof(WORD), compare_FindGlyph);
1057
1058 if (!ptr)
1059 return -1;
1060
1061 for (k = (ptr - pwLogClust)-1; k >= 0 && pwLogClust[k] == target; k--)
1062 ;
1063 k++;
1064
1065 return k;
1066}
static int __cdecl compare_FindGlyph(const void *a, const void *b)
Definition: usp10.c:1028
GLenum target
Definition: glext.h:7315
static PVOID ptr
Definition: dispmode.c:27
BOOL ascending
Definition: usp10.c:726

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 681 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:682
LIST_ENTRY ProcessLocksList
Definition: winbase.h:883
#define DWORD_PTR
Definition: treelist.c:76

Definition at line 682 of file usp10.c.

◆ script_cache_list

struct list script_cache_list = LIST_INIT(script_cache_list)
static

Definition at line 689 of file usp10.c.

Referenced by init_script_cache().

◆ script_props

const SCRIPT_PROPERTIES* script_props[]
static

Definition at line 636 of file usp10.c.

Referenced by ScriptGetProperties().

◆ script_ranges

const struct usp10_script_range script_ranges[]
static

Referenced by get_char_script().

◆ scriptInformation