typedef struct {
HDC hdc;
+ LONG height;
+ WCHAR default_char;
} ScriptCache;
typedef struct {
HeapFree(GetProcessHeap(), 0, mem);
}
+static HDC get_cache_hdc(SCRIPT_CACHE *psc)
+{
+ return ((ScriptCache *)*psc)->hdc;
+}
+
+static WCHAR get_cache_default_char(SCRIPT_CACHE *psc)
+{
+ return ((ScriptCache *)*psc)->default_char;
+}
+
+static LONG get_cache_height(SCRIPT_CACHE *psc)
+{
+ return ((ScriptCache *)*psc)->height;
+}
+
+static HRESULT init_script_cache(const HDC hdc, ScriptCache *sc)
+{
+ TEXTMETRICW metric;
+
+ if (!GetTextMetricsW(hdc, &metric)) return E_INVALIDARG;
+ sc->height = metric.tmHeight;
+ sc->default_char = metric.tmDefaultChar;
+ sc->hdc = hdc;
+ return S_OK;
+}
+
static HRESULT get_script_cache(const HDC hdc, SCRIPT_CACHE *psc)
{
if (!psc) return E_INVALIDARG;
if (!*psc)
{
+ HRESULT ret;
+ ScriptCache *sc;
+
if (!hdc) return E_PENDING;
- if (!(*psc = usp_alloc(sizeof(ScriptCache)))) return E_OUTOFMEMORY;
- ((ScriptCache *)*psc)->hdc = hdc;
+ if (!(sc = usp_zero_alloc(sizeof(ScriptCache)))) return E_OUTOFMEMORY;
+ if ((ret = init_script_cache(hdc, sc)))
+ {
+ usp_free(sc);
+ return ret;
+ }
+ *psc = sc;
}
+ TRACE("<- %p\n", *psc);
return S_OK;
}
*/
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
{
- switch(fdwReason) {
- case DLL_PROCESS_ATTACH:
- DisableThreadLibraryCalls(hInstDLL);
- break;
- case DLL_PROCESS_DETACH:
- break;
+ switch(fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hInstDLL);
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
}
return TRUE;
}
HRESULT WINAPI ScriptGetFontProperties(HDC hdc, SCRIPT_CACHE *psc, SCRIPT_FONTPROPERTIES *sfp)
{
HRESULT hr;
- TEXTMETRICW ptm;
TRACE("%p,%p,%p\n", hdc, psc, sfp);
/* return something sensible? */
sfp->wgBlank = 0;
- if (GetTextMetricsW(((ScriptCache *)*psc)->hdc, &ptm))
- sfp->wgDefault = ptm.tmDefaultChar;
- else
- sfp->wgDefault = 0;
+ sfp->wgDefault = get_cache_default_char(psc);
sfp->wgInvalid = 0;
sfp->wgKashida = 0xffff;
sfp->iKashidaWidth = 0;
* CONTEXT or NONE in reality */
if (!sds) return E_POINTER;
-
+
locale = ConvertDefaultLocale(locale);
if (!IsValidLocale(locale, LCID_INSTALLED))
return E_INVALIDARG;
-
+
plgid = PRIMARYLANGID(LANGIDFROMLCID(locale));
sds->TraditionalDigitLanguage = plgid;
/***********************************************************************
* 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,
+HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItems,
+ const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState,
SCRIPT_ITEM *pItems, int *pcItems)
{
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);
int runningX = 0;
int runningCp = 0;
StringAnalysis* analysis = ssa;
+
TRACE("(%p), %d, %d, (%p)\n", ssa, icp, fTrailing, pX);
- if(!ssa || !pX)
- {
- return 1;
- }
+ if (!ssa || !pX) return S_FALSE;
/* icp out of range */
if(icp < 0)
TRACE("(%p), %d, (%p), (%p)\n", ssa, iX, piCh, piTrailing);
- if(!ssa || !piCh || !piTrailing)
- {
- return 1;
- }
+ if (!ssa || !piCh || !piTrailing) return S_FALSE;
/* out of range */
if(iX < 0)
{
*piCh = -1;
*piTrailing = TRUE;
- return S_OK;
+ return S_OK;
}
for(i=0; i<analysis->numItems; i++)
*piCP = cChars;
*piTrailing = FALSE;
return S_OK;
- }
+ }
fAvePosX = fMaxPosX / cGlyphs;
iPosX = fAvePosX;
*piTrailing = 0;
else
*piTrailing = 1; /* yep we are over halfway */
-
+
*piCP = item -1; /* Return character position */
TRACE("*piCP=%d iPposX=%d\n", *piCP, iPosX);
return S_OK;
/***********************************************************************
* ScriptShape (USP10.@)
*
+ * Produce glyphs and visual attributes for a run.
+ *
+ * PARAMS
+ * hdc [I] Device context.
+ * psc [I/O] Opaque pointer to a script cache.
+ * pwcChars [I] Array of characters specifying the run.
+ * cChars [I] Number of characters in pwcChars.
+ * cMaxGlyphs [I] Length of pwOutGlyphs.
+ * psa [I/O] String analysis.
+ * pwOutGlyphs [O] Array of glyphs.
+ * pwLogClust [O] Array of logical cluster info.
+ * psva [O] Array of visual attributes.
+ * pcGlyphs [O] Number of glyphs returned.
+ *
+ * RETURNS
+ * Success: S_OK
+ * Failure: Non-zero HRESULT value.
*/
HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
int cChars, int cMaxGlyphs,
TRACE("\n");
if (!psa->fNoGlyphIndex) { /* Glyph translate */
- if (!(GetGlyphIndicesW(((ScriptCache *)*psc)->hdc, pwcChars, cChars, pwOutGlyphs, 0)))
+ if (!(GetGlyphIndicesW(get_cache_hdc(psc), pwcChars, cChars, pwOutGlyphs, 0)))
return S_FALSE;
TRACE("After: ");
/***********************************************************************
* ScriptPlace (USP10.@)
*
+ * Produce advance widths for a run.
+ *
+ * PARAMS
+ * hdc [I] Device context.
+ * psc [I/O] Opaque pointer to a script cache.
+ * pwGlyphs [I] Array of glyphs.
+ * cGlyphs [I] Number of glyphs in pwGlyphs.
+ * psva [I] Array of visual attributes.
+ * psa [I/O] String analysis.
+ * piAdvance [O] Array of advance widths.
+ * pGoffset [O] Glyph offsets.
+ * pABC [O] Combined ABC width.
+ *
+ * RETURNS
+ * Success: S_OK
+ * Failure: Non-zero HRESULT value.
*/
HRESULT WINAPI ScriptPlace(HDC hdc, SCRIPT_CACHE *psc, const WORD *pwGlyphs,
int cGlyphs, const SCRIPT_VISATTR *psva,
if (!(lpABC = usp_zero_alloc(sizeof(ABC) * cGlyphs))) return E_OUTOFMEMORY;
+ memset(pABC, 0, sizeof(ABC));
+
/* FIXME: set pGoffset to more reasonable values */
- if (!GetCharABCWidthsI(((ScriptCache *)*psc)->hdc, 0, cGlyphs, (WORD *) pwGlyphs, lpABC ))
+ if (!GetCharABCWidthsI(get_cache_hdc(psc), 0, cGlyphs, (WORD *) pwGlyphs, lpABC ))
{
WARN("Could not get ABC values\n");
for (wcnt = 0; wcnt < cGlyphs; wcnt++) {
TRACE("%4x",pwcInChars[cnt]);
TRACE("\n");
- GetGlyphIndicesW(((ScriptCache *)*psc)->hdc, pwcInChars, cChars, pwOutGlyphs, 0);
+ GetGlyphIndicesW(get_cache_hdc(psc), pwcInChars, cChars, pwOutGlyphs, 0);
TRACE("After: ");
for (cnt = 0; cnt < cChars; cnt++) {
if (!psa->fNoGlyphIndex) /* Have Glyphs? */
fuOptions |= ETO_GLYPH_INDEX; /* Say don't do translation to glyph */
- if (!ExtTextOutW(((ScriptCache *)*psc)->hdc, x, y, fuOptions, lprc, pwGlyphs, cGlyphs, NULL))
+ if (!ExtTextOutW(get_cache_hdc(psc), x, y, fuOptions, lprc, pwGlyphs, cGlyphs, NULL))
return S_FALSE;
return S_OK;
HRESULT WINAPI ScriptCacheGetHeight(HDC hdc, SCRIPT_CACHE *psc, LONG *height)
{
HRESULT hr;
- TEXTMETRICW metric;
TRACE("(%p, %p, %p)\n", hdc, psc, height);
if (!height) return E_INVALIDARG;
if ((hr = get_script_cache(hdc, psc))) return hr;
- /* FIXME: get this from the cache */
- if (!GetTextMetricsW(((ScriptCache *)*psc)->hdc, &metric)) return E_INVALIDARG;
-
- *height = metric.tmHeight;
+ *height = get_cache_height(psc);
return S_OK;
}
if ((hr = get_script_cache(hdc, psc))) return hr;
/* FIXME: get this from the cache */
- if (!GetCharABCWidthsW(((ScriptCache *)*psc)->hdc, glyph, glyph, abc)) return E_HANDLE;
+ if (!GetCharABCWidthsW(get_cache_hdc(psc), glyph, glyph, abc)) return E_HANDLE;
return S_OK;
}
{
unsigned int i, j;
StringAnalysis *analysis = ssa;
- TEXTMETRICW metric;
TRACE("(%p)\n", ssa);
if (!analysis->sz)
{
- if (!(analysis->sz = usp_alloc(sizeof(SIZE))))
- return NULL;
-
- /* FIXME: These values should be calculated at a more
- * appropriate place so that we can just pass cached
- * values here.
- */
- if (!GetTextMetricsW(analysis->sc->hdc, &metric))
- {
- usp_free(analysis->sz);
- analysis->sz = NULL;
- return NULL;
- }
- analysis->sz->cy = metric.tmHeight;
+ if (!(analysis->sz = usp_alloc(sizeof(SIZE)))) return NULL;
+ analysis->sz->cy = analysis->sc->height;
analysis->sz->cx = 0;
for (i = 0; i < analysis->numItems; i++)