ReactOS 0.4.16-dev-1946-g52006dd
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 short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
GLdouble s
Definition: gl.h:2039
GLuint res
Definition: glext.h:9613
GLuint index
Definition: glext.h:6031
GLsizei levels
Definition: glext.h:7884
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define S_OK
Definition: intsafe.h:52
#define debugstr_wn
Definition: kernel32.h:33
#define 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
_In_ size_t cnt
Definition: wcstombs.cpp:43
__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:156
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:754

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

2211{
2212 if (pva[glyph].fClusterStart)
2213 return TRUE;
2215 return TRUE;
2216
2217 return FALSE;
2218}
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 count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
Definition: pdh_main.c:96
#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:1856

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:20
BOOL WINAPI GetStringTypeW(DWORD type, LPCWSTR src, INT count, LPWORD chartype)
Definition: locale.c:3098
static const struct usp10_script_range script_ranges[]
static DWORD decode_surrogate_pair(const WCHAR *str, unsigned int index, unsigned int end)
Definition: usp10.c: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
#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:273
#define CT_CTYPE2
Definition: winnls.h:256
#define CT_CTYPE1
Definition: winnls.h:255

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

2818{
2819 int glyph_start;
2820 int glyph_end;
2821 int i, advance;
2822
2823 if (direction > 0)
2824 i = 0;
2825 else
2826 i = (cChars - 1);
2827
2828 for (glyph_start = -1, glyph_end = -1; i < cChars && i >= 0 && (glyph_start < 0 || glyph_end < 0); i+=direction)
2829 {
2830 if (glyph_start < 0 && pwLogClust[i] != cluster) continue;
2831 if (pwLogClust[i] == cluster && glyph_start < 0) glyph_start = pwLogClust[i];
2832 if (glyph_start >= 0 && glyph_end < 0 && pwLogClust[i] != cluster) glyph_end = pwLogClust[i];
2833 }
2834 if (glyph_end < 0)
2835 {
2836 if (direction > 0)
2837 glyph_end = cGlyphs;
2838 else
2839 {
2840 /* Don't fully understand multi-glyph reversed clusters yet,
2841 * do they occur for real or just in our test? */
2842 FIXME("multi-glyph reversed clusters found\n");
2843 glyph_end = glyph_start + 1;
2844 }
2845 }
2846
2847 /* Check for fClusterStart, finding this generally would mean a malformed set of data */
2848 for (i = glyph_start+1; i< glyph_end; i++)
2849 {
2850 if (psva[i].fClusterStart)
2851 {
2852 glyph_end = i;
2853 break;
2854 }
2855 }
2856
2857 for (advance = 0, i = glyph_start; i < glyph_end; i++)
2858 advance += piAdvance[i];
2859
2860 return advance;
2861}
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
#define FIXME(fmt,...)
Definition: precomp.h:53
direction
Definition: netio.c:882
_In_ FONTOBJ _In_ ULONG _In_ ULONG cGlyphs
Definition: winddi.h:3799

Referenced by ScriptXtoCP().

◆ get_cluster_data()

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

Definition at line 2781 of file usp10.c.

2782{
2783 int size = 0;
2784 int i;
2785
2786 for (i = 0; i < cChars; i++)
2787 {
2788 if (pwLogClust[i] == cluster_index)
2789 {
2790 if (!size && start_index)
2791 {
2792 *start_index = i;
2793 if (!cluster_size)
2794 return TRUE;
2795 }
2796 size++;
2797 }
2798 else if (size) break;
2799 }
2800 if (cluster_size)
2801 *cluster_size = size;
2802
2803 return (size > 0);
2804}
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 2615 of file usp10.c.

2617{
2618 int clust_size = 1;
2619 int check;
2620 WORD clust = pwLogClust[item];
2621
2622 for (check = item+direction; check < cChars && check >= 0; check+=direction)
2623 {
2624 if (pwLogClust[check] == clust)
2625 {
2626 clust_size ++;
2627 if (iCluster && *iCluster == -1)
2628 *iCluster = item;
2629 }
2630 else break;
2631 }
2632
2633 if (check_out)
2634 *check_out = check;
2635
2636 return clust_size;
2637}
#define check(expected, result)
Definition: dplayx.c:32

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

2640{
2641 int advance;
2642 int log_clust_max;
2643
2644 advance = piAdvance[glyph];
2645
2646 if (pwLogClust[0] > pwLogClust[cChars-1])
2647 log_clust_max = pwLogClust[0];
2648 else
2649 log_clust_max = pwLogClust[cChars-1];
2650
2651 if (glyph > log_clust_max)
2652 return advance;
2653
2654 for (glyph+=direction; glyph < cGlyphs && glyph >= 0; glyph +=direction)
2655 {
2656
2658 break;
2659 if (glyph > log_clust_max)
2660 break;
2661 advance += piAdvance[glyph];
2662 }
2663
2664 return advance;
2665}
static BOOL does_glyph_start_cluster(const SCRIPT_VISATTR *pva, const WORD *pwLogClust, int cChars, int glyph, int direction)
Definition: usp10.c:2210

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:1019
#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:2780
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:3575
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:3480

Referenced by enum_proc().

◆ ScriptApplyLogicalWidth()

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

Definition at line 4070 of file usp10.c.

4074{
4075 int i;
4076
4077 FIXME("(%p, %d, %d, %p, %p, %p, %p, %p, %p)\n",
4078 dx, num_chars, num_glyphs, log_clust, sva, advance, sa, abc, justify);
4079
4080 for (i = 0; i < num_chars; i++) justify[i] = advance[i];
4081 return S_OK;
4082}
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 3068 of file usp10.c.

3069{
3070 TRACE("(%s, %d, %p, %p)\n", debugstr_wn(chars, count), count, sa, la);
3071
3072 if (count < 0 || !la) return E_INVALIDARG;
3073 if (count == 0) return E_FAIL;
3074
3075 BREAK_line(chars, count, sa, la);
3076
3077 return S_OK;
3078}
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 3701 of file usp10.c.

3702{
3703 HRESULT hr;
3704
3705 TRACE("(%p, %p, %p)\n", hdc, psc, height);
3706
3707 if (!height) return E_INVALIDARG;
3708 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3709
3711 return S_OK;
3712}
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 2671 of file usp10.c.

2680{
2681 int item;
2682 float iPosX;
2683 int iSpecial = -1;
2684 int iCluster = -1;
2685 int clust_size = 1;
2686 float special_size = 0.0;
2687 int iMaxPos = 0;
2688 int advance = 0;
2689 BOOL rtl = FALSE;
2690
2691 TRACE("(%d,%d,%d,%d,%p,%p,%p,%p,%p)\n",
2692 iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance,
2693 psa, piX);
2694
2695 if (psa->fRTL && ! psa->fLogicalOrder)
2696 rtl = TRUE;
2697
2698 if (fTrailing)
2699 iCP++;
2700
2701 if (rtl)
2702 {
2703 int max_clust = pwLogClust[0];
2704
2705 for (item=0; item < cGlyphs; item++)
2706 if (pwLogClust[item] > max_clust)
2707 {
2708 ERR("We do not handle non reversed clusters properly\n");
2709 break;
2710 }
2711
2712 iMaxPos = 0;
2713 for (item = max_clust; item >=0; item --)
2714 iMaxPos += piAdvance[item];
2715 }
2716
2717 iPosX = 0.0;
2718 for (item=0; item < iCP && item < cChars; item++)
2719 {
2720 if (iSpecial == -1 && (iCluster == -1 || iCluster+clust_size <= item))
2721 {
2722 int check;
2723 int clust = pwLogClust[item];
2724
2725 iCluster = -1;
2726 clust_size = get_cluster_size(pwLogClust, cChars, item, 1, &iCluster,
2727 &check);
2728
2729 advance = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, clust, 1);
2730
2731 if (check >= cChars && !iMaxPos)
2732 {
2733 int glyph;
2734 for (glyph = clust; glyph < cGlyphs; glyph++)
2735 special_size += get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, glyph, 1);
2736 iSpecial = item;
2737 special_size /= (cChars - item);
2738 iPosX += special_size;
2739 }
2740 else
2741 {
2743 {
2744 clust_size --;
2745 if (clust_size == 0)
2746 iPosX += advance;
2747 }
2748 else
2749 iPosX += advance / (float)clust_size;
2750 }
2751 }
2752 else if (iSpecial != -1)
2753 iPosX += special_size;
2754 else /* (iCluster != -1) */
2755 {
2756 int adv = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, pwLogClust[iCluster], 1);
2758 {
2759 clust_size --;
2760 if (clust_size == 0)
2761 iPosX += adv;
2762 }
2763 else
2764 iPosX += adv / (float)clust_size;
2765 }
2766 }
2767
2768 if (iMaxPos > 0)
2769 {
2770 iPosX = iMaxPos - iPosX;
2771 if (iPosX < 0)
2772 iPosX = 0;
2773 }
2774
2775 *piX = iPosX;
2776 TRACE("*piX=%d\n", *piX);
2777 return S_OK;
2778}
#define ERR(fmt,...)
Definition: precomp.h:57
static int get_cluster_size(const WORD *pwLogClust, int cChars, int item, int direction, int *iCluster, int *check_out)
Definition: usp10.c:2615
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:2639
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 3575 of file usp10.c.

3577{
3578 HRESULT hr;
3579 int i;
3580
3581 TRACE("(%p,%p,%s,%d,0x%x,%p)\n", hdc, psc, debugstr_wn(pwcInChars, cChars),
3583
3584 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3585
3586 hr = S_OK;
3587
3588 for (i = 0; i < cChars; i++)
3589 {
3590 WCHAR inChar;
3591 if (dwFlags == SGCM_RTL)
3592 inChar = mirror_char(pwcInChars[i]);
3593 else
3594 inChar = pwcInChars[i];
3595 if (!(pwOutGlyphs[i] = get_cache_glyph(psc, inChar)))
3596 {
3597 WORD glyph;
3598 if (!hdc) return E_PENDING;
3599 if (GetGlyphIndicesW(hdc, &inChar, 1, &glyph, GGI_MARK_NONEXISTING_GLYPHS) == GDI_ERROR) return S_FALSE;
3600 if (glyph == 0xffff)
3601 {
3602 hr = S_FALSE;
3603 glyph = 0x0;
3604 }
3605 pwOutGlyphs[i] = set_cache_glyph(psc, inChar, glyph);
3606 }
3607 }
3608
3609 return hr;
3610}
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
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define SGCM_RTL
Definition: usp10.h:61
#define S_FALSE
Definition: winerror.h:3451
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 4113 of file usp10.c.

4114{
4115 HRESULT hr;
4116 if (!pFeatureTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4117 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4118
4120}
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 4104 of file usp10.c.

4105{
4106 HRESULT hr;
4107 if (!pLangSysTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4108 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4109
4111}
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 4095 of file usp10.c.

4096{
4097 HRESULT hr;
4098 if (!pScriptTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
4099 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
4100
4102}
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 3729 of file usp10.c.

3730{
3731 HRESULT hr;
3732
3733 TRACE("(%p, %p, 0x%04x, %p)\n", hdc, psc, glyph, abc);
3734
3735 if (!abc) return E_INVALIDARG;
3736 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3737
3738 if (!get_cache_glyph_widths(psc, glyph, abc))
3739 {
3740 if (!hdc) return E_PENDING;
3742 {
3743 if (!GetCharABCWidthsI(hdc, 0, 1, &glyph, abc)) return S_FALSE;
3744 }
3745 else
3746 {
3747 INT width;
3748 if (!GetCharWidthI(hdc, glyph, 1, NULL, &width)) return S_FALSE;
3749 abc->abcB = width;
3750 abc->abcA = abc->abcC = 0;
3751 }
3753 }
3754 return S_OK;
3755}
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:1857
UINT abcB
Definition: wingdi.h:1858
int abcC
Definition: wingdi.h:1859
BOOL WINAPI GetCharWidthI(_In_ HDC hdc, _In_ UINT giFirst, _In_ UINT cgi, _In_reads_opt_(cgi) LPWORD pgi, _Out_writes_(cgi) LPINT piWidths)
#define TMPF_TRUETYPE
Definition: wingdi.h:1313
BOOL WINAPI GetCharABCWidthsI(_In_ HDC hdc, _In_ UINT giFirst, _In_ UINT cgi, _In_reads_opt_(cgi) LPWORD pgi, _Out_writes_(cgi) LPABC pabc)

Referenced by test_ScriptGetGlyphABCWidth().

◆ ScriptGetLogicalWidths()

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

Definition at line 4019 of file usp10.c.

4022{
4023 int i, next = 0, direction;
4024
4025 TRACE("(%p, %d, %d, %p, %p, %p, %p)\n",
4026 sa, nbchars, nbglyphs, advances, log_clust, sva, widths);
4027
4028 if (sa->fRTL && !sa->fLogicalOrder)
4029 direction = -1;
4030 else
4031 direction = 1;
4032
4033 for (i = 0; i < nbchars; i++)
4034 {
4035 int clust_size = get_cluster_size(log_clust, nbchars, i, direction, NULL, NULL);
4036 int advance = get_glyph_cluster_advance(advances, sva, log_clust, nbglyphs, nbchars, log_clust[i], direction);
4037 int j;
4038
4039 for (j = 0; j < clust_size; j++)
4040 {
4041 widths[next] = advance / clust_size;
4042 next++;
4043 if (j) i++;
4044 }
4045 }
4046
4047 return S_OK;
4048}
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 3095 of file usp10.c.

3096{
3097 enum usp10_script script;
3098 unsigned int i, consumed;
3099
3100 TRACE("(%s,%d,0x%x)\n", debugstr_wn(chars, len), len, flag);
3101
3102 if (!chars || len < 0)
3103 return E_INVALIDARG;
3104
3105 for (i = 0; i < len; i+=consumed)
3106 {
3107 if ((flag & SIC_ASCIIDIGIT) && chars[i] >= 0x30 && chars[i] <= 0x39)
3108 return S_OK;
3109
3110 script = get_char_script(chars,i,len, &consumed);
3111 if ((scriptInformation[script].props.fComplex && (flag & SIC_COMPLEX))||
3113 return S_OK;
3114 }
3115 return S_FALSE;
3116}
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 4084 of file usp10.c.

4086{
4087 int i;
4088
4089 FIXME("(%p, %p, %d, %d, %d, %p)\n", sva, advance, num_glyphs, dx, min_kashida, justify);
4090
4091 for (i = 0; i < num_glyphs; i++) justify[i] = advance[i];
4092 return S_OK;
4093}

◆ ScriptLayout()

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

Definition at line 3773 of file usp10.c.

3774{
3775 int* indexs;
3776 int ich;
3777
3778 TRACE("(%d, %p, %p, %p)\n", runs, level, vistolog, logtovis);
3779
3780 if (!level || (!vistolog && !logtovis))
3781 return E_INVALIDARG;
3782
3783 if (!(indexs = heap_calloc(runs, sizeof(*indexs))))
3784 return E_OUTOFMEMORY;
3785
3786 if (vistolog)
3787 {
3788 for( ich = 0; ich < runs; ich++)
3789 indexs[ich] = ich;
3790
3791 ich = 0;
3792 while (ich < runs)
3793 ich += BIDI_ReorderV2lLevel(0, indexs+ich, level+ich, runs - ich, FALSE);
3794 memcpy(vistolog, indexs, runs * sizeof(*vistolog));
3795 }
3796
3797 if (logtovis)
3798 {
3799 for( ich = 0; ich < runs; ich++)
3800 indexs[ich] = ich;
3801
3802 ich = 0;
3803 while (ich < runs)
3804 ich += BIDI_ReorderL2vLevel(0, indexs+ich, level+ich, runs - ich, FALSE);
3805 memcpy(logtovis, indexs, runs * sizeof(*logtovis));
3806 }
3807 heap_free(indexs);
3808
3809 return S_OK;
3810}
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 3531 of file usp10.c.

3534{
3535 HRESULT hr;
3536 SCRIPT_GLYPHPROP *glyphProps;
3537 int i;
3538
3539 TRACE("(%p, %p, %p, %d, %p, %p, %p, %p, %p)\n", hdc, psc, pwGlyphs, cGlyphs, psva, psa,
3540 piAdvance, pGoffset, pABC);
3541
3542 if (!psva) return E_INVALIDARG;
3543 if (!pGoffset) return E_FAIL;
3544
3545 if (!(glyphProps = heap_calloc(cGlyphs, sizeof(*glyphProps))))
3546 return E_OUTOFMEMORY;
3547
3548 for (i = 0; i < cGlyphs; i++)
3549 glyphProps[i].sva = psva[i];
3550
3551 hr = ScriptPlaceOpenType(hdc, psc, psa, scriptInformation[psa->eScript].scriptTag, 0, NULL, NULL, 0, NULL, NULL, NULL, 0, pwGlyphs, glyphProps, cGlyphs, piAdvance, pGoffset, pABC);
3552
3553 heap_free(glyphProps);
3554
3555 return hr;
3556}
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:3408

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

3417{
3418 HRESULT hr;
3419 int i;
3420 static int once = 0;
3421
3422 TRACE("(%p, %p, %p, %s, %s, %p, %p, %d, %s, %p, %p, %d, %p, %p, %d, %p %p %p)\n",
3423 hdc, psc, psa,
3424 debugstr_an((char*)&tagScript,4), debugstr_an((char*)&tagLangSys,4),
3426 pwLogClust, pCharProps, cChars, pwGlyphs, pGlyphProps, cGlyphs, piAdvance,
3427 pGoffset, pABC);
3428
3429 if (!pGlyphProps) return E_INVALIDARG;
3430 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3431 if (!pGoffset) return E_FAIL;
3432
3433 if (cRanges)
3434 if (!once++) FIXME("Ranges not supported yet\n");
3435
3436 ((ScriptCache *)*psc)->userScript = tagScript;
3437 ((ScriptCache *)*psc)->userLang = tagLangSys;
3438
3439 if (pABC) memset(pABC, 0, sizeof(ABC));
3440 for (i = 0; i < cGlyphs; i++)
3441 {
3442 WORD glyph;
3443 ABC abc;
3444
3445 /* FIXME: set to more reasonable values */
3446 pGoffset[i].du = pGoffset[i].dv = 0;
3447
3448 if (pGlyphProps[i].sva.fZeroWidth)
3449 {
3450 abc.abcA = abc.abcB = abc.abcC = 0;
3451 if (piAdvance) piAdvance[i] = 0;
3452 continue;
3453 }
3454
3455 if (psa->fNoGlyphIndex)
3456 {
3457 if (FAILED(hr = ScriptGetCMap(hdc, psc, &pwGlyphs[i], 1, 0, &glyph))) return hr;
3458 }
3459 else
3460 {
3461 hr = S_OK;
3462 glyph = pwGlyphs[i];
3463 }
3464
3465 if (hr == S_FALSE)
3466 {
3467 if (!hdc) return E_PENDING;
3469 {
3470 if (!GetCharABCWidthsW(hdc, pwGlyphs[i], pwGlyphs[i], &abc)) return S_FALSE;
3471 }
3472 else
3473 {
3474 INT width;
3475 if (!GetCharWidthW(hdc, pwGlyphs[i], pwGlyphs[i], &width)) return S_FALSE;
3476 abc.abcB = width;
3477 abc.abcA = abc.abcC = 0;
3478 }
3479 }
3480 else if (!get_cache_glyph_widths(psc, glyph, &abc))
3481 {
3482 if (!hdc) return E_PENDING;
3484 {
3485 if (!GetCharABCWidthsI(hdc, glyph, 1, NULL, &abc)) return S_FALSE;
3486 }
3487 else
3488 {
3489 INT width;
3490 if (!GetCharWidthI(hdc, glyph, 1, NULL, &width)) return S_FALSE;
3491 abc.abcB = width;
3492 abc.abcA = abc.abcC = 0;
3493 }
3494 set_cache_glyph_widths(psc, glyph, &abc);
3495 }
3496 if (pABC)
3497 {
3498 pABC->abcA += abc.abcA;
3499 pABC->abcB += abc.abcB;
3500 pABC->abcC += abc.abcC;
3501 }
3502 if (piAdvance) piAdvance[i] = abc.abcA + abc.abcB + abc.abcC;
3503 }
3504
3505 SHAPE_ApplyOpenTypePositions(hdc, (ScriptCache *)*psc, psa, pwGlyphs, cGlyphs, piAdvance, pGoffset);
3506
3507 if (pABC) TRACE("Total for run: abcA=%d, abcB=%d, abcC=%d\n", pABC->abcA, pABC->abcB, pABC->abcC);
3508 return S_OK;
3509}
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: locale.c:2925
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1675
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: locale.c:2879
#define LANG_FARSI
Definition: nls.h:55
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#define LANG_ARABIC
Definition: nls.h:29
#define PRIMARYLANGID(l)
Definition: nls.h:16
DWORD TraditionalDigitLanguage
Definition: usp10.h:156
#define LCID_INSTALLED
Definition: winnls.h:214

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

3346{
3347 HRESULT hr;
3348 int i;
3349 SCRIPT_CHARPROP *charProps;
3350 SCRIPT_GLYPHPROP *glyphProps;
3351
3352 if (!psva || !pcGlyphs) return E_INVALIDARG;
3353 if (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
3354
3355 if (!(charProps = heap_calloc(cChars, sizeof(*charProps))))
3356 return E_OUTOFMEMORY;
3357
3358 if (!(glyphProps = heap_calloc(cMaxGlyphs, sizeof(*glyphProps))))
3359 {
3360 heap_free(charProps);
3361 return E_OUTOFMEMORY;
3362 }
3363
3365
3366 if (SUCCEEDED(hr))
3367 {
3368 for (i = 0; i < *pcGlyphs; i++)
3369 psva[i] = glyphProps[i].sva;
3370 }
3371
3372 heap_free(charProps);
3373 heap_free(glyphProps);
3374
3375 return hr;
3376}
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:3145
#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 3145 of file usp10.c.

3153{
3154 HRESULT hr;
3155 int i;
3156 unsigned int g;
3157 BOOL rtl;
3158 int cluster;
3159 static int once = 0;
3160
3161 TRACE("(%p, %p, %p, %s, %s, %p, %p, %d, %s, %d, %d, %p, %p, %p, %p, %p )\n",
3162 hdc, psc, psa,
3163 debugstr_an((char*)&tagScript,4), debugstr_an((char*)&tagLangSys,4),
3166
3167 if (psa) TRACE("psa values: %d, %d, %d, %d, %d, %d, %d\n", psa->eScript, psa->fRTL, psa->fLayoutRTL,
3168 psa->fLinkBefore, psa->fLinkAfter, psa->fLogicalOrder, psa->fNoGlyphIndex);
3169
3170 if (!pOutGlyphProps || !pcGlyphs || !pCharProps) return E_INVALIDARG;
3171 if (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
3172
3173 if (cRanges)
3174 if(!once++) FIXME("Ranges not supported yet\n");
3175
3176 rtl = (psa && !psa->fLogicalOrder && psa->fRTL);
3177
3178 *pcGlyphs = cChars;
3179 if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
3180 if (!pwLogClust) return E_FAIL;
3181
3182 ((ScriptCache *)*psc)->userScript = tagScript;
3183 ((ScriptCache *)*psc)->userLang = tagLangSys;
3184
3185 /* Initialize a SCRIPT_VISATTR and LogClust for each char in this run */
3186 for (i = 0; i < cChars; i++)
3187 {
3188 int idx = i;
3189 if (rtl) idx = cChars - 1 - i;
3190 /* FIXME: set to better values */
3191 pOutGlyphProps[i].sva.uJustification = (pwcChars[idx] == ' ') ? SCRIPT_JUSTIFY_BLANK : SCRIPT_JUSTIFY_CHARACTER;
3192 pOutGlyphProps[i].sva.fClusterStart = 1;
3193 pOutGlyphProps[i].sva.fDiacritic = 0;
3194 pOutGlyphProps[i].sva.fZeroWidth = 0;
3195 pOutGlyphProps[i].sva.fReserved = 0;
3196 pOutGlyphProps[i].sva.fShapeReserved = 0;
3197
3198 /* FIXME: have the shaping engine set this */
3199 pCharProps[i].fCanGlyphAlone = 0;
3200
3201 pwLogClust[i] = idx;
3202 }
3203
3204 if (psa && !psa->fNoGlyphIndex && ((ScriptCache *)*psc)->sfnt)
3205 {
3206 WCHAR *rChars;
3208
3209 if (!(rChars = heap_calloc(cChars, sizeof(*rChars))))
3210 return E_OUTOFMEMORY;
3211
3212 for (i = 0, g = 0, cluster = 0; i < cChars; i++)
3213 {
3214 int idx = i;
3215 DWORD chInput;
3216
3217 if (rtl) idx = cChars - 1 - i;
3218 if (!cluster)
3219 {
3221 if (!chInput)
3222 {
3223 if (psa->fRTL)
3224 chInput = mirror_char(pwcChars[idx]);
3225 else
3226 chInput = pwcChars[idx];
3227 rChars[i] = chInput;
3228 }
3229 else
3230 {
3231 rChars[i] = pwcChars[idx];
3232 rChars[i+1] = pwcChars[(rtl)?idx-1:idx+1];
3233 cluster = 1;
3234 }
3235 if (!(pwOutGlyphs[g] = get_cache_glyph(psc, chInput)))
3236 {
3237 WORD glyph;
3238 if (!hdc)
3239 {
3240 heap_free(rChars);
3241 return E_PENDING;
3242 }
3243 if (OpenType_CMAP_GetGlyphIndex(hdc, (ScriptCache *)*psc, chInput, &glyph, 0) == GDI_ERROR)
3244 {
3245 heap_free(rChars);
3246 return S_FALSE;
3247 }
3248 pwOutGlyphs[g] = set_cache_glyph(psc, chInput, glyph);
3249 }
3250 g++;
3251 }
3252 else
3253 {
3254 int k;
3255 cluster--;
3257 for (k = (rtl)?idx-1:idx+1; k >= 0 && k < cChars; (rtl)?k--:k++)
3258 pwLogClust[k]--;
3259 }
3260 }
3261 *pcGlyphs = g;
3262
3266
3267 for (i = 0; i < cChars; ++i)
3268 {
3269 /* Special case for tabs and joiners. As control characters, ZWNJ
3270 * and ZWJ would in principle get handled by the corresponding
3271 * shaping functions. However, since ZWNJ and ZWJ can get merged
3272 * into adjoining runs during itemisation, these don't generally
3273 * get classified as Script_Control. */
3274 if (pwcChars[i] == 0x0009 || pwcChars[i] == ZWSP || pwcChars[i] == ZWNJ || pwcChars[i] == ZWJ)
3275 {
3276 pwOutGlyphs[pwLogClust[i]] = ((ScriptCache *)*psc)->sfp.wgBlank;
3277 pOutGlyphProps[pwLogClust[i]].sva.fZeroWidth = 1;
3278 }
3279 }
3280 heap_free(rChars);
3281 }
3282 else
3283 {
3284 TRACE("no glyph translation\n");
3285 for (i = 0; i < cChars; i++)
3286 {
3287 int idx = i;
3288 /* No mirroring done here */
3289 if (rtl) idx = cChars - 1 - i;
3291
3292 if (!psa)
3293 continue;
3294
3295 /* overwrite some basic control glyphs to blank */
3296 if (psa->fNoGlyphIndex)
3297 {
3298 if (pwcChars[idx] == ZWSP || pwcChars[idx] == ZWNJ || pwcChars[idx] == ZWJ)
3299 {
3300 pwOutGlyphs[i] = 0x20;
3301 pOutGlyphProps[i].sva.fZeroWidth = 1;
3302 }
3303 }
3304 else if (psa->eScript == Script_Control || pwcChars[idx] == ZWSP
3305 || pwcChars[idx] == ZWNJ || pwcChars[idx] == ZWJ)
3306 {
3307 if (pwcChars[idx] == 0x0009 || pwcChars[idx] == 0x000A ||
3308 pwcChars[idx] == 0x000D || pwcChars[idx] >= 0x001C)
3309 {
3310 pwOutGlyphs[i] = ((ScriptCache *)*psc)->sfp.wgBlank;
3311 pOutGlyphProps[i].sva.fZeroWidth = 1;
3312 }
3313 }
3314 }
3315 }
3316
3317 return S_OK;
3318}
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:209
@ 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 3959 of file usp10.c.

3960{
3961 StringAnalysis *analysis = ssa;
3962
3963 TRACE("(%p)\n", ssa);
3964
3965 if (!analysis) return NULL;
3966 return &analysis->clip_len;
3967}
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 3936 of file usp10.c.

3937{
3938 StringAnalysis *analysis = ssa;
3939
3940 TRACE("(%p)\n", ssa);
3941
3942 if (!analysis) return NULL;
3943 if (!(analysis->ssa_flags & SSA_BREAK)) return NULL;
3944 return analysis->logattrs;
3945}
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 3897 of file usp10.c.

3898{
3899 int i, j;
3900 StringAnalysis *analysis = ssa;
3901
3902 TRACE("(%p)\n", ssa);
3903
3904 if (!analysis) return NULL;
3905 if (!(analysis->ssa_flags & SSA_GLYPHS)) return NULL;
3906
3907 if (!(analysis->flags & SCRIPT_STRING_ANALYSIS_FLAGS_SIZE))
3908 {
3909 analysis->sz.cy = analysis->glyphs[0].sc->tm.tmHeight;
3910
3911 analysis->sz.cx = 0;
3912 for (i = 0; i < analysis->numItems; i++)
3913 {
3914 if (analysis->glyphs[i].sc->tm.tmHeight > analysis->sz.cy)
3915 analysis->sz.cy = analysis->glyphs[i].sc->tm.tmHeight;
3916 for (j = 0; j < analysis->glyphs[i].numGlyphs; j++)
3917 analysis->sz.cx += analysis->glyphs[i].piAdvance[j];
3918 }
3920 }
3921 return &analysis->sz;
3922}
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:2829
#define SSA_GLYPHS
Definition: usp10.h:40

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

◆ ScriptStringAnalyse()

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

Definition at line 1985 of file usp10.c.

1991{
1993 StringAnalysis *analysis = NULL;
1994 SCRIPT_CONTROL sControl;
1995 SCRIPT_STATE sState;
1996#ifdef __REACTOS__ // CORE-20176 & CORE-20177
1997 int i, num_items = cString + 1;
1998#else
1999 int i, num_items = 255;
2000#endif
2001 BYTE *BidiLevel;
2002 WCHAR *iString = NULL;
2003#ifdef __REACTOS__ // CORE-20176 & CORE-20177
2005#endif
2006
2007 TRACE("(%p,%p,%d,%d,%d,0x%x,%d,%p,%p,%p,%p,%p,%p)\n",
2008 hdc, pString, cString, cGlyphs, iCharset, dwFlags, iReqWidth,
2009 psControl, psState, piDx, pTabdef, pbInClass, pssa);
2010
2011 if (iCharset != -1)
2012 {
2013 FIXME("Only Unicode strings are supported\n");
2014 return E_INVALIDARG;
2015 }
2016 if (cString < 1 || !pString) return E_INVALIDARG;
2017 if ((dwFlags & SSA_GLYPHS) && !hdc) return E_PENDING;
2018
2019 if (!(analysis = heap_alloc_zero(sizeof(*analysis))))
2020 return E_OUTOFMEMORY;
2021#ifdef __REACTOS__ // CORE-20176 & CORE-20177
2022 if (!(analysis->pItem = heap_calloc(num_items, sizeof(*analysis->pItem))))
2023#else
2024 if (!(analysis->pItem = heap_calloc(num_items + 1, sizeof(*analysis->pItem))))
2025#endif
2026 goto error;
2027
2028 /* FIXME: handle clipping */
2029 analysis->clip_len = cString;
2030 analysis->hdc = hdc;
2031 analysis->ssa_flags = dwFlags;
2032
2033 if (psState)
2034 sState = *psState;
2035 else
2036 memset(&sState, 0, sizeof(SCRIPT_STATE));
2037
2038 if (psControl)
2039 sControl = *psControl;
2040 else
2041 memset(&sControl, 0, sizeof(SCRIPT_CONTROL));
2042
2043 if (dwFlags & SSA_PASSWORD)
2044 {
2045 if (!(iString = heap_calloc(cString, sizeof(*iString))))
2046 {
2047 hr = E_OUTOFMEMORY;
2048 goto error;
2049 }
2050 for (i = 0; i < cString; i++)
2051 iString[i] = *((const WCHAR *)pString);
2052 pString = iString;
2053 }
2054
2055 hr = ScriptItemize(pString, cString, num_items, &sControl, &sState, analysis->pItem,
2056 &analysis->numItems);
2057
2058 if (FAILED(hr))
2059#ifdef __REACTOS__ // CORE-20176 & CORE-20177
2060 goto error;
2061#else
2062 {
2063 if (hr == E_OUTOFMEMORY)
2064 hr = E_INVALIDARG;
2065 goto error;
2066 }
2067#endif
2068
2069#ifdef __REACTOS__ // CORE-20176 & CORE-20177
2070 /* Having as many items as codepoints is the worst case scenario, try to reclaim some memory. */
2071 if ((items = heap_realloc(analysis->pItem, (analysis->numItems + 1) * sizeof(*analysis->pItem))))
2072 analysis->pItem = items;
2073#endif
2074
2075 /* set back to out of memory for default goto error behaviour */
2076 hr = E_OUTOFMEMORY;
2077
2078 if (dwFlags & SSA_BREAK)
2079 {
2080 if (!(analysis->logattrs = heap_calloc(cString, sizeof(*analysis->logattrs))))
2081 goto error;
2082
2083 for (i = 0; i < analysis->numItems; ++i)
2084 ScriptBreak(&((const WCHAR *)pString)[analysis->pItem[i].iCharPos],
2085 analysis->pItem[i + 1].iCharPos - analysis->pItem[i].iCharPos,
2086 &analysis->pItem[i].a, &analysis->logattrs[analysis->pItem[i].iCharPos]);
2087 }
2088
2089 if (!(analysis->logical2visual = heap_calloc(analysis->numItems, sizeof(*analysis->logical2visual))))
2090 goto error;
2091 if (!(BidiLevel = heap_alloc_zero(analysis->numItems)))
2092 goto error;
2093
2094 if (dwFlags & SSA_GLYPHS)
2095 {
2096 int tab_x = 0;
2097
2098 if (!(analysis->glyphs = heap_calloc(analysis->numItems, sizeof(*analysis->glyphs))))
2099 {
2100 heap_free(BidiLevel);
2101 goto error;
2102 }
2103
2104 for (i = 0; i < analysis->numItems; i++)
2105 {
2106 SCRIPT_CACHE *sc = (SCRIPT_CACHE*)&analysis->glyphs[i].sc;
2107 int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
2108 int numGlyphs = 1.5 * cChar + 16;
2109 WORD *glyphs = heap_calloc(numGlyphs, sizeof(*glyphs));
2110 WORD *pwLogClust = heap_calloc(cChar, sizeof(*pwLogClust));
2111 int *piAdvance = heap_calloc(numGlyphs, sizeof(*piAdvance));
2112 SCRIPT_VISATTR *psva = heap_calloc(numGlyphs, sizeof(*psva));
2113 GOFFSET *pGoffset = heap_calloc(numGlyphs, sizeof(*pGoffset));
2114 int numGlyphsReturned;
2115 HFONT originalFont = 0x0;
2116
2117 /* FIXME: non unicode strings */
2118 const WCHAR* pStr = (const WCHAR*)pString;
2119 analysis->glyphs[i].fallbackFont = NULL;
2120
2121 if (!glyphs || !pwLogClust || !piAdvance || !psva || !pGoffset)
2122 {
2123 heap_free (BidiLevel);
2124 heap_free (glyphs);
2126 heap_free (piAdvance);
2127 heap_free (psva);
2128 heap_free (pGoffset);
2129 hr = E_OUTOFMEMORY;
2130 goto error;
2131 }
2132
2133 if ((dwFlags & SSA_FALLBACK) && requires_fallback(hdc, sc, &analysis->pItem[i].a, &pStr[analysis->pItem[i].iCharPos], cChar))
2134 {
2135 LOGFONTW lf;
2136 GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), & lf);
2138 lf.lfFaceName[0] = 0;
2139 find_fallback_font(analysis->pItem[i].a.eScript, lf.lfFaceName);
2140 if (lf.lfFaceName[0])
2141 {
2142 analysis->glyphs[i].fallbackFont = CreateFontIndirectW(&lf);
2143 if (analysis->glyphs[i].fallbackFont)
2144 {
2145 ScriptFreeCache(sc);
2146 originalFont = SelectObject(hdc, analysis->glyphs[i].fallbackFont);
2147 }
2148 }
2149 }
2150
2151 /* FIXME: When we properly shape Hangul remove this check */
2152 if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && analysis->pItem[i].a.eScript == Script_Hangul)
2153 analysis->pItem[i].a.fNoGlyphIndex = TRUE;
2154
2155 if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && !scriptInformation[analysis->pItem[i].a.eScript].props.fComplex && !analysis->pItem[i].a.fRTL)
2156 analysis->pItem[i].a.fNoGlyphIndex = TRUE;
2157
2158 ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos], cChar, numGlyphs,
2159 &analysis->pItem[i].a, glyphs, pwLogClust, psva, &numGlyphsReturned);
2160 hr = ScriptPlace(hdc, sc, glyphs, numGlyphsReturned, psva, &analysis->pItem[i].a,
2161 piAdvance, pGoffset, &analysis->glyphs[i].abc);
2162 if (originalFont)
2163 SelectObject(hdc,originalFont);
2164
2165 if (dwFlags & SSA_TAB)
2166 {
2167 int tabi = 0;
2168 for (tabi = 0; tabi < cChar; tabi++)
2169 {
2170 if (pStr[analysis->pItem[i].iCharPos+tabi] == 0x0009)
2171 piAdvance[tabi] = getGivenTabWidth(analysis->glyphs[i].sc, pTabdef, analysis->pItem[i].iCharPos+tabi, tab_x);
2172 tab_x+=piAdvance[tabi];
2173 }
2174 }
2175
2176 analysis->glyphs[i].numGlyphs = numGlyphsReturned;
2177 analysis->glyphs[i].glyphs = glyphs;
2178 analysis->glyphs[i].pwLogClust = pwLogClust;
2179 analysis->glyphs[i].piAdvance = piAdvance;
2180 analysis->glyphs[i].psva = psva;
2181 analysis->glyphs[i].pGoffset = pGoffset;
2182 analysis->glyphs[i].iMaxPosX= -1;
2183
2184 BidiLevel[i] = analysis->pItem[i].a.s.uBidiLevel;
2185 }
2186 }
2187 else
2188 {
2189 for (i = 0; i < analysis->numItems; i++)
2190 BidiLevel[i] = analysis->pItem[i].a.s.uBidiLevel;
2191 }
2192
2193 ScriptLayout(analysis->numItems, BidiLevel, NULL, analysis->logical2visual);
2194 heap_free(BidiLevel);
2195
2196 *pssa = analysis;
2197 heap_free(iString);
2198 return S_OK;
2199
2200error:
2201 heap_free(iString);
2202 heap_free(analysis->glyphs);
2203 heap_free(analysis->logattrs);
2204 heap_free(analysis->pItem);
2205 heap_free(analysis->logical2visual);
2206 heap_free(analysis);
2207 return hr;
2208}
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
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:3531
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:3342
HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *logtovis)
Definition: usp10.c:3773
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:3068
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 *)
static TCHAR * items[]
Definition: page1.c:45
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:1546
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)

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

◆ ScriptStringCPtoX()

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

Definition at line 2432 of file usp10.c.

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

2578{
2579 StringAnalysis* analysis;
2580 BOOL invalid;
2581 int i;
2582
2583 TRACE("(%p)\n", pssa);
2584
2585 if (!pssa || !(analysis = *pssa)) return E_INVALIDARG;
2586
2588
2589 if (analysis->glyphs)
2590 {
2591 for (i = 0; i < analysis->numItems; i++)
2592 {
2593 heap_free(analysis->glyphs[i].glyphs);
2594 heap_free(analysis->glyphs[i].pwLogClust);
2595 heap_free(analysis->glyphs[i].piAdvance);
2596 heap_free(analysis->glyphs[i].psva);
2597 heap_free(analysis->glyphs[i].pGoffset);
2598 if (analysis->glyphs[i].fallbackFont)
2599 DeleteObject(analysis->glyphs[i].fallbackFont);
2600 ScriptFreeCache((SCRIPT_CACHE *)&analysis->glyphs[i].sc);
2601 heap_free(analysis->glyphs[i].sc);
2602 }
2603 heap_free(analysis->glyphs);
2604 }
2605
2606 heap_free(analysis->pItem);
2607 heap_free(analysis->logattrs);
2608 heap_free(analysis->logical2visual);
2609 heap_free(analysis);
2610
2611 if (invalid) return E_INVALIDARG;
2612 return S_OK;
2613}
pKey DeleteObject()

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

◆ ScriptStringGetLogicalWidths()

HRESULT WINAPI ScriptStringGetLogicalWidths ( SCRIPT_STRING_ANALYSIS  ssa,
int piDx 
)

Definition at line 3825 of file usp10.c.

3826{
3827 int i, j, next = 0;
3828 StringAnalysis *analysis = ssa;
3829
3830 TRACE("%p, %p\n", ssa, piDx);
3831
3832 if (!analysis) return S_FALSE;
3833 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
3834
3835 for (i = 0; i < analysis->numItems; i++)
3836 {
3837 int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
3838 int direction = 1;
3839
3840 if (analysis->pItem[i].a.fRTL && ! analysis->pItem[i].a.fLogicalOrder)
3841 direction = -1;
3842
3843 for (j = 0; j < cChar; j++)
3844 {
3845 int k;
3846 int glyph = analysis->glyphs[i].pwLogClust[j];
3847 int clust_size = get_cluster_size(analysis->glyphs[i].pwLogClust,
3848 cChar, j, direction, NULL, NULL);
3849 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);
3850
3851 for (k = 0; k < clust_size; k++)
3852 {
3853 piDx[next] = advance / clust_size;
3854 next++;
3855 if (k) j++;
3856 }
3857 }
3858 }
3859 return S_OK;
3860}
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 3982 of file usp10.c.

3983{
3984 int i, j;
3985 unsigned int k;
3986 StringAnalysis *analysis = ssa;
3987
3988 TRACE("(%p)\n", ssa);
3989
3990 if (!analysis) return S_FALSE;
3991 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
3992
3993 /* FIXME: handle RTL scripts */
3994 for (i = 0, k = 0; i < analysis->numItems; i++)
3995 for (j = 0; j < analysis->glyphs[i].numGlyphs; j++, k++)
3996 order[k] = k;
3997
3998 return S_OK;
3999}
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 2387 of file usp10.c.

2395{
2396 StringAnalysis *analysis;
2397 int item;
2398 HRESULT hr;
2399
2400 TRACE("(%p,%d,%d,0x%08x,%s,%d,%d,%d)\n",
2401 ssa, iX, iY, uOptions, wine_dbgstr_rect(prc), iMinSel, iMaxSel, fDisabled);
2402
2403 if (!(analysis = ssa)) return E_INVALIDARG;
2404 if (!(analysis->ssa_flags & SSA_GLYPHS)) return E_INVALIDARG;
2405
2406 for (item = 0; item < analysis->numItems; item++)
2407 {
2408 hr = SS_ItemOut( ssa, iX, iY, analysis->logical2visual[item], -1, -1, uOptions, prc, FALSE, fDisabled);
2409 if (FAILED(hr))
2410 return hr;
2411 }
2412
2413 if (iMinSel < iMaxSel && (iMinSel > 0 || iMaxSel > 0))
2414 {
2415 if (iMaxSel > 0 && iMinSel < 0)
2416 iMinSel = 0;
2417 for (item = 0; item < analysis->numItems; item++)
2418 {
2419 hr = SS_ItemOut( ssa, iX, iY, analysis->logical2visual[item], iMinSel, iMaxSel, uOptions, prc, TRUE, fDisabled);
2420 if (FAILED(hr))
2421 return hr;
2422 }
2423 }
2424
2425 return S_OK;
2426}
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:2221
_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 3875 of file usp10.c.

3876{
3877 StringAnalysis *analysis = ssa;
3878
3879 TRACE("(%p)\n", ssa);
3880
3881 if (!analysis) return E_INVALIDARG;
3883}

◆ ScriptStringXtoCP()

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

Definition at line 2495 of file usp10.c.

2496{
2497 StringAnalysis* analysis = ssa;
2498 int item;
2499
2500 TRACE("(%p), %d, (%p), (%p)\n", ssa, iX, piCh, piTrailing);
2501
2502 if (!ssa || !piCh || !piTrailing) return S_FALSE;
2503 if (!(analysis->ssa_flags & SSA_GLYPHS)) return S_FALSE;
2504
2505 /* out of range */
2506 if(iX < 0)
2507 {
2508 if (analysis->pItem[0].a.fRTL)
2509 {
2510 *piCh = 1;
2511 *piTrailing = FALSE;
2512 }
2513 else
2514 {
2515 *piCh = -1;
2516 *piTrailing = TRUE;
2517 }
2518 return S_OK;
2519 }
2520
2521 for(item=0; item<analysis->numItems; item++)
2522 {
2523 int i;
2524 int CP;
2525
2526 for (i = 0; i < analysis->numItems && analysis->logical2visual[i] != item; i++)
2527 /* nothing */;
2528
2529 CP = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
2530 /* initialize max extents for uninitialized runs */
2531 if (analysis->glyphs[i].iMaxPosX == -1)
2532 {
2533 if (analysis->pItem[i].a.fRTL)
2534 ScriptCPtoX(0, FALSE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2535 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2536 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2537 else
2538 ScriptCPtoX(CP, TRUE, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2539 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2540 &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX);
2541 }
2542
2543 if (iX > analysis->glyphs[i].iMaxPosX)
2544 {
2545 iX -= analysis->glyphs[i].iMaxPosX;
2546 continue;
2547 }
2548
2549 ScriptXtoCP(iX, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust,
2550 analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance,
2551 &analysis->pItem[i].a, piCh, piTrailing);
2552 *piCh += analysis->pItem[i].iCharPos;
2553
2554 return S_OK;
2555 }
2556
2557 /* out of range */
2558 *piCh = analysis->pItem[analysis->numItems].iCharPos;
2559 *piTrailing = FALSE;
2560
2561 return S_OK;
2562}
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:2875

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

3620{
3621 HRESULT hr = S_OK;
3622 INT i, dir = 1;
3623 INT *lpDx;
3624 WORD *reordered_glyphs = (WORD *)pwGlyphs;
3625
3626 TRACE("(%p, %p, %d, %d, %08x, %s, %p, %p, %d, %p, %d, %p, %p, %p)\n",
3627 hdc, psc, x, y, fuOptions, wine_dbgstr_rect(lprc), psa, pwcReserved, iReserved, pwGlyphs, cGlyphs,
3628 piAdvance, piJustify, pGoffset);
3629
3630 if (!hdc || !psc) return E_INVALIDARG;
3631 if (!piAdvance || !psa || !pwGlyphs) return E_INVALIDARG;
3632
3633 fuOptions &= ETO_CLIPPED + ETO_OPAQUE;
3634 fuOptions |= ETO_IGNORELANGUAGE;
3635 if (!psa->fNoGlyphIndex) /* Have Glyphs? */
3636 fuOptions |= ETO_GLYPH_INDEX; /* Say don't do translation to glyph */
3637
3638 if (!(lpDx = heap_calloc(cGlyphs, 2 * sizeof(*lpDx))))
3639 return E_OUTOFMEMORY;
3640 fuOptions |= ETO_PDY;
3641
3642 if (psa->fRTL && psa->fLogicalOrder)
3643 {
3644 if (!(reordered_glyphs = heap_calloc(cGlyphs, sizeof(*reordered_glyphs))))
3645 {
3646 heap_free( lpDx );
3647 return E_OUTOFMEMORY;
3648 }
3649
3650 for (i = 0; i < cGlyphs; i++)
3651 reordered_glyphs[i] = pwGlyphs[cGlyphs - 1 - i];
3652 dir = -1;
3653 }
3654
3655 for (i = 0; i < cGlyphs; i++)
3656 {
3657 int orig_index = (dir > 0) ? i : cGlyphs - 1 - i;
3658 lpDx[i * 2] = piAdvance[orig_index];
3659 lpDx[i * 2 + 1] = 0;
3660
3661 if (pGoffset)
3662 {
3663 if (i == 0)
3664 {
3665 x += pGoffset[orig_index].du * dir;
3666 y += pGoffset[orig_index].dv;
3667 }
3668 else
3669 {
3670 lpDx[(i - 1) * 2] += pGoffset[orig_index].du * dir;
3671 lpDx[(i - 1) * 2 + 1] += pGoffset[orig_index].dv;
3672 }
3673 lpDx[i * 2] -= pGoffset[orig_index].du * dir;
3674 lpDx[i * 2 + 1] -= pGoffset[orig_index].dv;
3675 }
3676 }
3677
3678 if (!ExtTextOutW(hdc, x, y, fuOptions, lprc, reordered_glyphs, cGlyphs, lpDx))
3679 hr = S_FALSE;
3680
3681 if (reordered_glyphs != pwGlyphs) heap_free( reordered_glyphs );
3682 heap_free(lpDx);
3683
3684 return hr;
3685}
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:4568

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

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

Referenced by init_script_cache().

◆ set_cache_glyph()

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

Definition at line 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 2221 of file usp10.c.

2231{
2232 StringAnalysis *analysis;
2233 int off_x = 0;
2234 HRESULT hr;
2235 COLORREF BkColor = 0x0;
2236 COLORREF TextColor = 0x0;
2237 INT BkMode = 0;
2238 INT runStart, runEnd;
2239 INT iGlyph, cGlyphs;
2240 HFONT oldFont = 0x0;
2241 RECT crc;
2242 int i;
2243
2244 TRACE("(%p,%d,%d,%d,%d,%d, 0x%1x, %d, %d)\n",
2245 ssa, iX, iY, iItem, cStart, cEnd, uOptions, fSelected, fDisabled);
2246
2247 if (!(analysis = ssa)) return E_INVALIDARG;
2248
2249 if ((cStart >= 0 && analysis->pItem[iItem+1].iCharPos <= cStart) ||
2250 (cEnd >= 0 && analysis->pItem[iItem].iCharPos >= cEnd))
2251 return S_OK;
2252
2253 CopyRect(&crc,prc);
2254 if (fSelected)
2255 {
2256 BkMode = GetBkMode(analysis->hdc);
2257 SetBkMode( analysis->hdc, OPAQUE);
2258 BkColor = GetBkColor(analysis->hdc);
2260 if (!fDisabled)
2261 {
2262 TextColor = GetTextColor(analysis->hdc);
2264 }
2265 }
2266 if (analysis->glyphs[iItem].fallbackFont)
2267 oldFont = SelectObject(analysis->hdc, analysis->glyphs[iItem].fallbackFont);
2268
2269 if (cStart >= 0 && analysis->pItem[iItem+1].iCharPos > cStart && analysis->pItem[iItem].iCharPos <= cStart)
2270 runStart = cStart - analysis->pItem[iItem].iCharPos;
2271 else
2272 runStart = 0;
2273 if (cEnd >= 0 && analysis->pItem[iItem+1].iCharPos > cEnd && analysis->pItem[iItem].iCharPos <= cEnd)
2274 runEnd = (cEnd-1) - analysis->pItem[iItem].iCharPos;
2275 else
2276 runEnd = (analysis->pItem[iItem+1].iCharPos - analysis->pItem[iItem].iCharPos) - 1;
2277
2278 if (analysis->pItem[iItem].a.fRTL)
2279 {
2280 if (cEnd >= 0 && cEnd < analysis->pItem[iItem+1].iCharPos)
2281 ScriptStringCPtoX(ssa, cEnd, FALSE, &off_x);
2282 else
2283 ScriptStringCPtoX(ssa, analysis->pItem[iItem+1].iCharPos-1, TRUE, &off_x);
2284 crc.left = iX + off_x;
2285 }
2286 else
2287 {
2288 if (cStart >=0 && runStart)
2289 ScriptStringCPtoX(ssa, cStart, FALSE, &off_x);
2290 else
2291 ScriptStringCPtoX(ssa, analysis->pItem[iItem].iCharPos, FALSE, &off_x);
2292 crc.left = iX + off_x;
2293 }
2294
2295 if (analysis->pItem[iItem].a.fRTL)
2296 iGlyph = analysis->glyphs[iItem].pwLogClust[runEnd];
2297 else
2298 iGlyph = analysis->glyphs[iItem].pwLogClust[runStart];
2299
2300 if (analysis->pItem[iItem].a.fRTL)
2301 cGlyphs = analysis->glyphs[iItem].pwLogClust[runStart] - iGlyph;
2302 else
2303 cGlyphs = analysis->glyphs[iItem].pwLogClust[runEnd] - iGlyph;
2304
2305 cGlyphs++;
2306
2307 /* adjust for cluster glyphs when starting */
2308 if (analysis->pItem[iItem].a.fRTL)
2309 i = analysis->pItem[iItem+1].iCharPos - 1;
2310 else
2311 i = analysis->pItem[iItem].iCharPos;
2312
2313 for (; i >=analysis->pItem[iItem].iCharPos && i < analysis->pItem[iItem+1].iCharPos; (analysis->pItem[iItem].a.fRTL)?i--:i++)
2314 {
2315 if (analysis->glyphs[iItem].pwLogClust[i - analysis->pItem[iItem].iCharPos] == iGlyph)
2316 {
2317 if (analysis->pItem[iItem].a.fRTL)
2318 ScriptStringCPtoX(ssa, i, TRUE, &off_x);
2319 else
2320 ScriptStringCPtoX(ssa, i, FALSE, &off_x);
2321 break;
2322 }
2323 }
2324
2325 if (cEnd < 0 || scriptInformation[analysis->pItem[iItem].a.eScript].props.fNeedsCaretInfo)
2326 {
2327 INT direction;
2328 INT clust_glyph;
2329
2330 clust_glyph = iGlyph + cGlyphs;
2331 if (analysis->pItem[iItem].a.fRTL)
2332 direction = -1;
2333 else
2334 direction = 1;
2335
2336 while(clust_glyph < analysis->glyphs[iItem].numGlyphs &&
2337 !does_glyph_start_cluster(analysis->glyphs[iItem].psva, analysis->glyphs[iItem].pwLogClust, (analysis->pItem[iItem+1].iCharPos - analysis->pItem[iItem].iCharPos), clust_glyph, direction))
2338 {
2339 cGlyphs++;
2340 clust_glyph++;
2341 }
2342 }
2343
2344 hr = ScriptTextOut(analysis->hdc,
2345 (SCRIPT_CACHE *)&analysis->glyphs[iItem].sc, iX + off_x,
2346 iY, uOptions, &crc, &analysis->pItem[iItem].a, NULL, 0,
2347 &analysis->glyphs[iItem].glyphs[iGlyph], cGlyphs,
2348 &analysis->glyphs[iItem].piAdvance[iGlyph], NULL,
2349 &analysis->glyphs[iItem].pGoffset[iGlyph]);
2350
2351 TRACE("ScriptTextOut hr=%08x\n", hr);
2352
2353 if (fSelected)
2354 {
2355 SetBkColor(analysis->hdc, BkColor);
2356 SetBkMode( analysis->hdc, BkMode);
2357 if (!fDisabled)
2358 SetTextColor(analysis->hdc, TextColor);
2359 }
2360 if (analysis->glyphs[iItem].fallbackFont)
2361 SelectObject(analysis->hdc, oldFont);
2362
2363 return hr;
2364}
HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrailing, int *pX)
Definition: usp10.c:2432
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:3616
Definition: windef.h:99
LONG left
Definition: windef.h:100
DWORD COLORREF
Definition: windef.h:94
int WINAPI GetBkMode(_In_ HDC)
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
COLORREF WINAPI GetTextColor(_In_ HDC)
Definition: text.c:860
COLORREF WINAPI GetBkColor(_In_ HDC)
Definition: dc.c:978
#define OPAQUE
Definition: wingdi.h:949
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1056
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:917
DWORD WINAPI GetSysColor(_In_ int)
BOOL WINAPI CopyRect(_Out_ LPRECT, _In_ LPCRECT)
#define COLOR_HIGHLIGHT
Definition: winuser.h:937
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:938

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
static PVOID ptr
Definition: dispmode.c:27
BOOL ascending
Definition: usp10.c:726
Definition: tools.h:99

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

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( uniscribe  )

Variable Documentation

◆ cs_script_cache

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

Definition at line 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
#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