⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usp10.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
 *   Success: S_OK
 *   Failure: E_INVALIDARG if sds is invalid. Otherwise an HRESULT.
 */
HRESULT WINAPI ScriptApplyDigitSubstitution(const SCRIPT_DIGITSUBSTITUTE *sds, 
                                            SCRIPT_CONTROL *sc, SCRIPT_STATE *ss)
{
    SCRIPT_DIGITSUBSTITUTE psds;

    TRACE("%p, %p, %p\n", sds, sc, ss);

    if (!sc || !ss) return E_POINTER;
    if (!sds)
    {
        sds = &psds;
        if (ScriptRecordDigitSubstitution(LOCALE_USER_DEFAULT, &psds) != S_OK)
            return E_INVALIDARG;
    }

    sc->uDefaultLanguage = LANG_ENGLISH;
    sc->fContextDigits = 0;
    ss->fDigitSubstitute = 0;

    switch (sds->DigitSubstitute) {
        case SCRIPT_DIGITSUBSTITUTE_CONTEXT:
        case SCRIPT_DIGITSUBSTITUTE_NATIONAL:
        case SCRIPT_DIGITSUBSTITUTE_NONE:
        case SCRIPT_DIGITSUBSTITUTE_TRADITIONAL:
            return S_OK;
        default:
            return E_INVALIDARG;
    }
}

/***********************************************************************
 *      ScriptItemize (USP10.@)
 *
 * Split a Unicode string into shapeable parts.
 *
 * PARAMS
 *  pwcInChars [I] String to split.
 *  cInChars   [I] Number of characters in pwcInChars.
 *  cMaxItems  [I] Maximum number of items to return.
 *  psControl  [I] Pointer to a SCRIPT_CONTROL structure.
 *  psState    [I] Pointer to a SCRIPT_STATE structure.
 *  pItems     [O] Buffer to receive SCRIPT_ITEM structures.
 *  pcItems    [O] Number of script items returned.
 *
 * RETURNS
 *  Success: S_OK
 *  Failure: Non-zero HRESULT value.
 */
HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItems,
                             const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState,
                             SCRIPT_ITEM *pItems, int *pcItems)
{

#define Numeric_start 0x0030
#define Numeric_stop  0x0039
#define Numeric_space 0x0020
#define Arabic_start  0x0600
#define Arabic_stop   0x06ff
#define Latin_start   0x0001
#define Latin_stop    0x024f
#define Script_Arabic  6
#define Script_Latin   1
#define Script_Numeric 5

    int   cnt = 0, index = 0;
    int   New_Script = SCRIPT_UNDEFINED;

    TRACE("%s,%d,%d,%p,%p,%p,%p\n", debugstr_wn(pwcInChars, cInChars), cInChars, cMaxItems, 
          psControl, psState, pItems, pcItems);

    if (!pwcInChars || !cInChars || !pItems || cMaxItems < 2)
        return E_INVALIDARG;

    pItems[index].iCharPos = 0;
    memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));

    if  (pwcInChars[cnt] >= Numeric_start && pwcInChars[cnt] <= Numeric_stop)
        pItems[index].a.eScript = Script_Numeric;
    else
    if  (pwcInChars[cnt] >= Arabic_start && pwcInChars[cnt] <= Arabic_stop)
        pItems[index].a.eScript = Script_Arabic;
    else
    if  (pwcInChars[cnt] >= Latin_start && pwcInChars[cnt] <= Latin_stop)
        pItems[index].a.eScript = Script_Latin;

    if  (pItems[index].a.eScript  == Script_Arabic)
        pItems[index].a.s.uBidiLevel = 1;

    TRACE("New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n",
          New_Script, pItems[index].a.eScript, index, cnt,
          pItems[index].iCharPos = cnt);

    for (cnt=0; cnt < cInChars; cnt++)
    {
        if  ((pwcInChars[cnt] >= Numeric_start && pwcInChars[cnt] <= Numeric_stop)
             || (New_Script == Script_Numeric && pwcInChars[cnt] == Numeric_space))
            New_Script = Script_Numeric;
        else
        if  ((pwcInChars[cnt] >= Arabic_start && pwcInChars[cnt] <= Arabic_stop)
             || (New_Script == Script_Arabic && pwcInChars[cnt] == Numeric_space))
            New_Script = Script_Arabic;
        else
        if  ((WCHAR) pwcInChars[cnt] >= Latin_start && (WCHAR) pwcInChars[cnt] <= Latin_stop)
            New_Script = Script_Latin;
        else
            New_Script = SCRIPT_UNDEFINED;

        if  (New_Script != pItems[index].a.eScript)
        {
            TRACE("New_Script=%d, eScript=%d ", New_Script, pItems[index].a.eScript);
            index++;
            if  (index+1 > cMaxItems)
                return E_OUTOFMEMORY;

            pItems[index].iCharPos = cnt;
            memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));

            if  (New_Script == Script_Arabic)
                pItems[index].a.s.uBidiLevel = 1;

            pItems[index].a.eScript = New_Script;
            if  (New_Script == Script_Arabic)
                pItems[index].a.s.uBidiLevel = 1;

            TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos = cnt);
        }
    }

    /* While not strictly necessary according to the spec, make sure the n+1
     * item is set up to prevent random behaviour if the caller erroneously
     * checks the n+1 structure                                              */
    memset(&pItems[index+1].a, 0, sizeof(SCRIPT_ANALYSIS));

    TRACE("index=%d cnt=%d iCharPos=%d\n", index+1, cnt, pItems[index+1].iCharPos = cnt);

    /*  Set one SCRIPT_STATE item being returned  */
    *pcItems = index + 1;

    /*  Set SCRIPT_ITEM                                     */
    pItems[index+1].iCharPos = cnt;       /* the last + 1 item
                                             contains the ptr to the lastchar */
    return S_OK;
}

/***********************************************************************
 *      ScriptStringAnalyse (USP10.@)
 *
 */
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)
{
    HRESULT hr = E_OUTOFMEMORY;
    StringAnalysis *analysis = NULL;
    int i, num_items = 255;

    TRACE("(%p,%p,%d,%d,%d,0x%x,%d,%p,%p,%p,%p,%p,%p)\n",
          hdc, pString, cString, cGlyphs, iCharset, dwFlags, iReqWidth,
          psControl, psState, piDx, pTabdef, pbInClass, pssa);

    if (iCharset != -1)
    {
        FIXME("Only Unicode strings are supported\n");
        return E_INVALIDARG;
    }
    if (cString < 1 || !pString) return E_INVALIDARG;
    if ((dwFlags & SSA_GLYPHS) && !hdc) return E_PENDING;

    if (!(analysis = usp_zero_alloc(sizeof(StringAnalysis)))) return E_OUTOFMEMORY;
    if (!(analysis->pItem = usp_zero_alloc(num_items * sizeof(SCRIPT_ITEM) + 1))) goto error;

    /* FIXME: handle clipping */
    analysis->clip_len = cString;

    hr = ScriptItemize(pString, cString, num_items, psControl, psState, analysis->pItem,
                       &analysis->numItems);

    while (hr == E_OUTOFMEMORY)
    {
        SCRIPT_ITEM *tmp;

        num_items *= 2;
        if (!(tmp = usp_zero_realloc(analysis->pItem, num_items * sizeof(SCRIPT_ITEM) + 1)))
            goto error;

        analysis->pItem = tmp;
        hr = ScriptItemize(pString, cString, num_items, psControl, psState, analysis->pItem,
                           &analysis->numItems);
    }
    if (hr) goto error;

    if ((analysis->logattrs = usp_alloc(sizeof(SCRIPT_LOGATTR) * cString)))
        ScriptBreak(pString, cString, (SCRIPT_STRING_ANALYSIS)analysis, analysis->logattrs);
    else
        goto error;

    if (!(analysis->glyphs = usp_zero_alloc(sizeof(StringGlyphs) * analysis->numItems)))
        goto error;

    for (i = 0; i < analysis->numItems; i++)
    {
        SCRIPT_CACHE *sc = (SCRIPT_CACHE *)&analysis->sc;
        int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
        int numGlyphs = 1.5 * cChar + 16;
        WORD *glyphs = usp_zero_alloc(sizeof(WORD) * numGlyphs);
        WORD *pwLogClust = usp_zero_alloc(sizeof(WORD) * cChar);
        int *piAdvance = usp_zero_alloc(sizeof(int) * numGlyphs);
        SCRIPT_VISATTR *psva = usp_zero_alloc(sizeof(SCRIPT_VISATTR) * cChar);
        GOFFSET *pGoffset = usp_zero_alloc(sizeof(GOFFSET) * numGlyphs);
        ABC *abc = usp_zero_alloc(sizeof(ABC));
        int numGlyphsReturned;

        /* FIXME: non unicode strings */
        WCHAR* pStr = (WCHAR*)pString;
        hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos],
                         cChar, numGlyphs, &analysis->pItem[i].a,
                         glyphs, pwLogClust, psva, &numGlyphsReturned);
        hr = ScriptPlace(hdc, sc, glyphs, numGlyphsReturned, psva, &analysis->pItem[i].a,
                         piAdvance, pGoffset, abc);

        analysis->glyphs[i].numGlyphs = numGlyphsReturned;
        analysis->glyphs[i].glyphs = glyphs;
        analysis->glyphs[i].pwLogClust = pwLogClust;
        analysis->glyphs[i].piAdvance = piAdvance;
        analysis->glyphs[i].psva = psva;
        analysis->glyphs[i].pGoffset = pGoffset;
        analysis->glyphs[i].abc = abc;
    }

    *pssa = analysis;
    return S_OK;

error:
    usp_free(analysis->glyphs);
    usp_free(analysis->logattrs);
    usp_free(analysis->pItem);
    usp_free(analysis);
    return hr;
}

/***********************************************************************
 *      ScriptStringOut (USP10.@)
 *
 * This function takes the output of ScriptStringAnalyse and joins the segments
 * of glyphs and passes the resulting string to ScriptTextOut.  ScriptStringOut
 * only processes glyphs.
 *
 * Parameters:
 *  ssa       [I] buffer to hold the analysed string components
 *  iX        [I] X axis displacement for output
 *  iY        [I] Y axis displacement for output
 *  uOptions  [I] flags controling output processing
 *  prc       [I] rectangle coordinates
 *  iMinSel   [I] starting pos for substringing output string
 *  iMaxSel   [I] ending pos for substringing output string
 *  fDisabled [I] controls text highlighting
 *
 *  RETURNS
 *   Success: S_OK
 *   Failure: is the value returned by ScriptTextOut
 */
HRESULT WINAPI ScriptStringOut(SCRIPT_STRING_ANALYSIS ssa,
                               int iX,
                               int iY, 
                               UINT uOptions, 
                               const RECT *prc, 
                               int iMinSel, 
                               int iMaxSel,
                               BOOL fDisabled)
{
    StringAnalysis *analysis;
    WORD *glyphs;
    int   item, cnt, x;
    HRESULT hr;

    TRACE("(%p,%d,%d,0x%1x,%p,%d,%d,%d)\n",
         ssa, iX, iY, uOptions, prc, iMinSel, iMaxSel, fDisabled);

    if (!(analysis = ssa)) return E_INVALIDARG;

    /*
     * Get storage for the output buffer for the consolidated strings
     */
    cnt = 0;
    for (item = 0; item < analysis->numItems; item++)
    {
        cnt += analysis->glyphs[item].numGlyphs;
    }
    if (!(glyphs = usp_alloc(sizeof(WCHAR) * cnt))) return E_OUTOFMEMORY;

    /*
     * ScriptStringOut only processes glyphs hence set ETO_GLYPH_INDEX
     */
    uOptions |= ETO_GLYPH_INDEX;
    analysis->pItem[0].a.fNoGlyphIndex = FALSE; /* say that we have glyphs */

    /*
     * Copy the string items into the output buffer
     */

    TRACE("numItems %d\n", analysis->numItems);

    cnt = 0;
    for (item = 0; item < analysis->numItems; item++)
    {
        memcpy(&glyphs[cnt], analysis->glyphs[item].glyphs,
              sizeof(WCHAR) * analysis->glyphs[item].numGlyphs);

        TRACE("Item %d, Glyphs %d ", item, analysis->glyphs[item].numGlyphs);
        for (x = cnt; x < analysis->glyphs[item].numGlyphs + cnt; x ++)
            TRACE("%04x", glyphs[x]);
        TRACE("\n");

        cnt += analysis->glyphs[item].numGlyphs; /* point to the end of the copied text */
    }

    hr = ScriptTextOut(analysis->sc->hdc, (SCRIPT_CACHE *)&analysis->sc, iX, iY,
                       uOptions, prc, &analysis->pItem->a, NULL, 0, glyphs, cnt,
                       analysis->glyphs->piAdvance, NULL, analysis->glyphs->pGoffset);
    TRACE("ScriptTextOut hr=%08x\n", hr);

    /*
     * Free the output buffer and script cache
     */
    usp_free(glyphs);
    return hr;
}

/***********************************************************************
 *      ScriptStringCPtoX (USP10.@)
 *
 */
HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrailing, int* pX)
{
    int i, j;
    int runningX = 0;
    int runningCp = 0;
    StringAnalysis* analysis = ssa;

    TRACE("(%p), %d, %d, (%p)\n", ssa, icp, fTrailing, pX);

    if (!ssa || !pX) return S_FALSE;

    /* icp out of range */
    if(icp < 0)
    {
        analysis->invalid = TRUE;
        return E_INVALIDARG;
    }

    for(i=0; i<analysis->numItems; i++)
    {
        for(j=0; j<analysis->glyphs[i].numGlyphs; j++)
        {
            if(runningCp == icp && fTrailing == FALSE)
            {
                *pX = runningX;
                return S_OK;
            }
            runningX += analysis->glyphs[i].piAdvance[j];
            if(runningCp == icp && fTrailing == TRUE)
            {
                *pX = runningX;
                return S_OK;
            }
            runningCp++;
        }
    }

    /* icp out of range */
    analysis->invalid = TRUE;
    return E_INVALIDARG;
}

/***********************************************************************
 *      ScriptStringXtoCP (USP10.@)
 *
 */
HRESULT WINAPI ScriptStringXtoCP(SCRIPT_STRING_ANALYSIS ssa, int iX, int* piCh, int* piTrailing) 
{
    StringAnalysis* analysis = ssa;
    int i;
    int j;
    int runningX = 0;
    int runningCp = 0;
    int width;

    TRACE("(%p), %d, (%p), (%p)\n", ssa, iX, piCh, piTrailing);

    if (!ssa || !piCh || !piTrailing) return S_FALSE;

    /* out of range */
    if(iX < 0)
    {
        *piCh = -1;
        *piTrailing = TRUE;
        return S_OK;
    }

    for(i=0; i<analysis->numItems; i++)
    {
        for(j=0; j<analysis->glyphs[i].numGlyphs; j++)
        {
            width = analysis->glyphs[i].piAdvance[j];
            if(iX < (runningX + width))
            {
                *piCh = runningCp;
                if((iX - runningX) > width/2)
                    *piTrailing = TRUE;
                else
                    *piTrailing = FALSE;
                return S_OK;
            }
            runningX += width;
            runningCp++;
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -