|
|
//// LPK_USP - Interface to Uniscribe String APIs
//
// Dave C Brown (dbrown) 13th December 1997.
//
// Copyright (c) 1996-7, Microsoft Corporation. All rights reserved.
//// LPK_ANA provides the main analysis entrypoint for the script engine
//
// ScriptStringAnalyse creates and returns a structure containing a
// variety of information about the string, optionally including:
//
// Glyphs and glyph attributes
// Glyph positions
// Cursor and word positions
#include "precomp.hxx"
#include "winnlsp.h" // import NlsGetCacheUpdateCount()
extern "C" WINGDIAPI BOOL WINAPI AnyLinkedFonts(); // GDI exports this but doesn't provide a header
///// LPK.H - Internal header
//
//
//. #include "usp10.h"
//. #include "usp10p.h"
//. #include "lpk_glob.h"
///// LpkStringAnalyse
//
// Build Uniscribe input flag structures
HRESULT LpkStringAnalyse( HDC hdc, //In Device context (required)
const void *pString, //In String in 8 or 16 bit characters
int cString, //In Length in characters
int cGlyphs, //In Required glyph buffer size (default cString*3/2 + 1)
int iCharset, //In Charset if an ANSI string, -1 for a Unicode string
DWORD dwFlags, //In Analysis required
int iDigitSubstitute, int iReqWidth, //In Required width for fit and/or clip
SCRIPT_CONTROL *psControl, //In Analysis control (optional)
SCRIPT_STATE *psState, //In Analysis initial state (optional)
const int *piDx, //In Requested logical dx array
SCRIPT_TABDEF *pTabdef, //In Tab positions (optional)
BYTE *pbInClass, //In Legacy GetCharacterPlacement character classifications (deprecated)
STRING_ANALYSIS **ppsa) { //Out Analysis of string
const SCRIPT_CONTROL emptySc = {0}; const SCRIPT_STATE emptySs = {0};
HRESULT hr; SCRIPT_CONTROL sc; SCRIPT_STATE ss; ULONG ulCsrCacheCount; SCRIPT_DIGITSUBSTITUTE sds;
ASSERTS(cString!=0, "LpkStringAnalyse: input string must contain at least one character");
TIMEENTRY(LSA, cString);
if (psControl) { sc = *psControl; } else { sc = emptySc; }
if (psState) { ss = *psState; } else { ss = emptySs; }
// Check to see if we need to update our NLS cached data
if ((ulCsrCacheCount=NlsGetCacheUpdateCount()) != g_ulNlsUpdateCacheCount) {
TRACE(NLS, ("LPK : Updating NLS cache, lpkNlsCacheCount=%ld, CsrssCacheCount=%ld", g_ulNlsUpdateCacheCount ,ulCsrCacheCount));
g_ulNlsUpdateCacheCount = ulCsrCacheCount;
// Update the cache now
ReadNLSScriptSettings(); }
// Select required digit substitution
if (iDigitSubstitute < 0) {
// Use NLS digit subtitution as selected by user through control panel
ScriptApplyDigitSubstitution(&g_DigitSubstitute, &sc, &ss);
} else {
// Override digit subtitution
sds = g_DigitSubstitute; sds.DigitSubstitute = iDigitSubstitute; ScriptApplyDigitSubstitution(&sds, &sc, &ss); }
// On Arabic systems, RTL fields start with the ENtoAN rule active.
if ( (dwFlags & SSA_RTL) && ( g_ACP == 1256 || g_UserPrimaryLanguage == LANG_ARABIC)) { ss.fArabicNumContext = TRUE; }
// When font linking is activated, it takes precedence over font fallback
// for non-complex scripts.
if (g_iUseFontLinking == -1) { g_iUseFontLinking = (int) AnyLinkedFonts(); }
if (g_iUseFontLinking) { dwFlags |= SSA_LINK;
}
sc.fLegacyBidiClass = TRUE; // All legacy APIs use legacy plus, minus, solidus classifications
//TRACEMSG(("LpkStringAnalyse: g_uLocaleLanguage %d, LANG_ARABIC %d, dwFlags & SSA_RTL %x, ss.fArabicNumContext %x",
// g_uLocaleLanguage, LANG_ARABIC, dwFlags & SSA_RTL, ss.fArabicNumContext));
hr = ScriptStringAnalyse( hdc, pString, cString, cGlyphs, iCharset, dwFlags, iReqWidth, &sc, &ss, piDx, pTabdef, pbInClass, (SCRIPT_STRING_ANALYSIS*)ppsa);
TIMEEXIT(LSA); return hr; }
///// ftsWordBreak - Support full text search wordbreaker
//
//
// Mar 9,1997 - [wchao]
//
extern "C" BOOL WINAPI ftsWordBreak ( PWSTR pInStr, INT cchInStr, PBYTE pResult, INT cchRes, INT charset) {
int ich; int ichRes; int ichPrev; HRESULT hr; STRING_ANALYSIS *psa;
UNREFERENCED_PARAMETER(cchRes) ;
// set up ED structure to prefer BasicAnalysis
//
hr = LpkStringAnalyse( NULL, pInStr, cchInStr, 0, charset, SSA_BREAK, -1, 0, NULL, NULL, NULL, NULL, NULL, &psa);
if (SUCCEEDED(hr)) {
for (ich=1, ichRes=0, ichPrev=0; ich < cchInStr; ich++) { if (psa->pLogAttr[ich].fSoftBreak) { pResult[ichRes] = ich - ichPrev; ichPrev = ich; ichRes++; } } pResult[ichRes] = 0; ScriptStringFree((void**)&psa);
} else {
ASSERTHR(hr, ("ftsWordBreak - LpkStringAnalyse"));
}
return TRUE; }
|