usp10: Move CMAP functions to opentype.c.
This commit is contained in:
parent
8c1b9a01bf
commit
6311ccfe97
|
@ -9,6 +9,7 @@ C_SRCS = \
|
|||
indicsyllable.c \
|
||||
linebreak.c \
|
||||
mirror.c \
|
||||
opentype.c \
|
||||
shape.c \
|
||||
shaping.c \
|
||||
usp10.c
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Opentype font interfaces for the Uniscribe Script Processor (usp10.dll)
|
||||
*
|
||||
* Copyright 2012 CodeWeavers, Aric Stewart
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "usp10.h"
|
||||
#include "winternl.h"
|
||||
|
||||
#include "usp10_internal.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(uniscribe);
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define GET_BE_WORD(x) (x)
|
||||
#define GET_BE_DWORD(x) (x)
|
||||
#else
|
||||
#define GET_BE_WORD(x) RtlUshortByteSwap(x)
|
||||
#define GET_BE_DWORD(x) RtlUlongByteSwap(x)
|
||||
#endif
|
||||
|
||||
/* These are all structures needed for the cmap format 12 table */
|
||||
#define CMAP_TAG MS_MAKE_TAG('c', 'm', 'a', 'p')
|
||||
|
||||
typedef struct {
|
||||
WORD platformID;
|
||||
WORD encodingID;
|
||||
DWORD offset;
|
||||
} CMAP_EncodingRecord;
|
||||
|
||||
typedef struct {
|
||||
WORD version;
|
||||
WORD numTables;
|
||||
CMAP_EncodingRecord tables[1];
|
||||
} CMAP_Header;
|
||||
|
||||
typedef struct {
|
||||
DWORD startCharCode;
|
||||
DWORD endCharCode;
|
||||
DWORD startGlyphID;
|
||||
} CMAP_SegmentedCoverage_group;
|
||||
|
||||
typedef struct {
|
||||
WORD format;
|
||||
WORD reserved;
|
||||
DWORD length;
|
||||
DWORD language;
|
||||
DWORD nGroups;
|
||||
CMAP_SegmentedCoverage_group groups[1];
|
||||
} CMAP_SegmentedCoverage;
|
||||
|
||||
|
||||
/**********
|
||||
* CMAP
|
||||
**********/
|
||||
|
||||
static VOID *load_CMAP_format12_table(HDC hdc, ScriptCache *psc)
|
||||
{
|
||||
CMAP_Header *CMAP_Table = NULL;
|
||||
int length;
|
||||
int i;
|
||||
|
||||
if (!psc->CMAP_Table)
|
||||
{
|
||||
length = GetFontData(hdc, CMAP_TAG , 0, NULL, 0);
|
||||
if (length != GDI_ERROR)
|
||||
{
|
||||
psc->CMAP_Table = HeapAlloc(GetProcessHeap(),0,length);
|
||||
GetFontData(hdc, CMAP_TAG , 0, psc->CMAP_Table, length);
|
||||
TRACE("Loaded cmap table of %i bytes\n",length);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CMAP_Table = psc->CMAP_Table;
|
||||
|
||||
for (i = 0; i < GET_BE_WORD(CMAP_Table->numTables); i++)
|
||||
{
|
||||
if ( (GET_BE_WORD(CMAP_Table->tables[i].platformID) == 3) &&
|
||||
(GET_BE_WORD(CMAP_Table->tables[i].encodingID) == 10) )
|
||||
{
|
||||
CMAP_SegmentedCoverage *format = (CMAP_SegmentedCoverage*)(((BYTE*)CMAP_Table) + GET_BE_DWORD(CMAP_Table->tables[i].offset));
|
||||
if (GET_BE_WORD(format->format) == 12)
|
||||
return format;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int compare_group(const void *a, const void* b)
|
||||
{
|
||||
const DWORD *chr = a;
|
||||
const CMAP_SegmentedCoverage_group *group = b;
|
||||
|
||||
if (*chr < GET_BE_DWORD(group->startCharCode))
|
||||
return -1;
|
||||
if (*chr > GET_BE_DWORD(group->endCharCode))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD OpenType_CMAP_GetGlyphIndex(HDC hdc, ScriptCache *psc, DWORD utf32c, LPWORD pgi, DWORD flags)
|
||||
{
|
||||
/* BMP: use gdi32 for ease */
|
||||
if (utf32c < 0x10000)
|
||||
{
|
||||
WCHAR ch = utf32c;
|
||||
return GetGlyphIndicesW(hdc,&ch, 1, pgi, flags);
|
||||
}
|
||||
|
||||
if (!psc->CMAP_format12_Table)
|
||||
psc->CMAP_format12_Table = load_CMAP_format12_table(hdc, psc);
|
||||
|
||||
if (flags & GGI_MARK_NONEXISTING_GLYPHS)
|
||||
*pgi = 0xffff;
|
||||
else
|
||||
*pgi = 0;
|
||||
|
||||
if (psc->CMAP_format12_Table)
|
||||
{
|
||||
CMAP_SegmentedCoverage *format = NULL;
|
||||
CMAP_SegmentedCoverage_group *group = NULL;
|
||||
|
||||
format = (CMAP_SegmentedCoverage *)psc->CMAP_format12_Table;
|
||||
|
||||
group = bsearch(&utf32c, format->groups, GET_BE_DWORD(format->nGroups),
|
||||
sizeof(CMAP_SegmentedCoverage_group), compare_group);
|
||||
|
||||
if (group)
|
||||
{
|
||||
DWORD offset = utf32c - GET_BE_DWORD(group->startCharCode);
|
||||
*pgi = GET_BE_DWORD(group->startGlyphID) + offset;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -315,37 +315,6 @@ typedef struct {
|
|||
GDEF_ClassRangeRecord ClassRangeRecord[1];
|
||||
} GDEF_ClassDefFormat2;
|
||||
|
||||
|
||||
/* These are all structures needed for the cmap format 12 table */
|
||||
#define CMAP_TAG MS_MAKE_TAG('c', 'm', 'a', 'p')
|
||||
|
||||
typedef struct {
|
||||
WORD platformID;
|
||||
WORD encodingID;
|
||||
DWORD offset;
|
||||
} CMAP_EncodingRecord;
|
||||
|
||||
typedef struct {
|
||||
WORD version;
|
||||
WORD numTables;
|
||||
CMAP_EncodingRecord tables[1];
|
||||
} CMAP_Header;
|
||||
|
||||
typedef struct {
|
||||
DWORD startCharCode;
|
||||
DWORD endCharCode;
|
||||
DWORD startGlyphID;
|
||||
} CMAP_SegmentedCoverage_group;
|
||||
|
||||
typedef struct {
|
||||
WORD format;
|
||||
WORD reserved;
|
||||
DWORD length;
|
||||
DWORD language;
|
||||
DWORD nGroups;
|
||||
CMAP_SegmentedCoverage_group groups[1];
|
||||
} CMAP_SegmentedCoverage;
|
||||
|
||||
static INT GSUB_apply_lookup(const GSUB_LookupList* lookup, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count);
|
||||
static HRESULT GSUB_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags, LPCVOID* script_table);
|
||||
static HRESULT GSUB_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags, LPCVOID* language_table);
|
||||
|
@ -3606,89 +3575,6 @@ HRESULT SHAPE_CheckFontForRequiredFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANA
|
|||
return USP_E_SCRIPT_NOT_IN_FONT;
|
||||
}
|
||||
|
||||
static VOID *load_CMAP_format12_table(HDC hdc, ScriptCache *psc)
|
||||
{
|
||||
CMAP_Header *CMAP_Table = NULL;
|
||||
int length;
|
||||
int i;
|
||||
|
||||
if (!psc->CMAP_Table)
|
||||
{
|
||||
length = GetFontData(hdc, CMAP_TAG , 0, NULL, 0);
|
||||
if (length != GDI_ERROR)
|
||||
{
|
||||
psc->CMAP_Table = HeapAlloc(GetProcessHeap(),0,length);
|
||||
GetFontData(hdc, CMAP_TAG , 0, psc->CMAP_Table, length);
|
||||
TRACE("Loaded cmap table of %i bytes\n",length);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CMAP_Table = psc->CMAP_Table;
|
||||
|
||||
for (i = 0; i < GET_BE_WORD(CMAP_Table->numTables); i++)
|
||||
{
|
||||
if ( (GET_BE_WORD(CMAP_Table->tables[i].platformID) == 3) &&
|
||||
(GET_BE_WORD(CMAP_Table->tables[i].encodingID) == 10) )
|
||||
{
|
||||
CMAP_SegmentedCoverage *format = (CMAP_SegmentedCoverage*)(((BYTE*)CMAP_Table) + GET_BE_DWORD(CMAP_Table->tables[i].offset));
|
||||
if (GET_BE_WORD(format->format) == 12)
|
||||
return format;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int compare_group(const void *a, const void* b)
|
||||
{
|
||||
const DWORD *chr = a;
|
||||
const CMAP_SegmentedCoverage_group *group = b;
|
||||
|
||||
if (*chr < GET_BE_DWORD(group->startCharCode))
|
||||
return -1;
|
||||
if (*chr > GET_BE_DWORD(group->endCharCode))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD CMAP_GetGlyphIndex(HDC hdc, ScriptCache *psc, DWORD utf32c, LPWORD pgi, DWORD flags)
|
||||
{
|
||||
/* BMP: use gdi32 for ease */
|
||||
if (utf32c < 0x10000)
|
||||
{
|
||||
WCHAR ch = utf32c;
|
||||
return GetGlyphIndicesW(hdc,&ch, 1, pgi, flags);
|
||||
}
|
||||
|
||||
if (!psc->CMAP_format12_Table)
|
||||
psc->CMAP_format12_Table = load_CMAP_format12_table(hdc, psc);
|
||||
|
||||
if (flags & GGI_MARK_NONEXISTING_GLYPHS)
|
||||
*pgi = 0xffff;
|
||||
else
|
||||
*pgi = 0;
|
||||
|
||||
if (psc->CMAP_format12_Table)
|
||||
{
|
||||
CMAP_SegmentedCoverage *format = NULL;
|
||||
CMAP_SegmentedCoverage_group *group = NULL;
|
||||
|
||||
format = (CMAP_SegmentedCoverage *)psc->CMAP_format12_Table;
|
||||
|
||||
group = bsearch(&utf32c, format->groups, GET_BE_DWORD(format->nGroups),
|
||||
sizeof(CMAP_SegmentedCoverage_group), compare_group);
|
||||
|
||||
if (group)
|
||||
{
|
||||
DWORD offset = utf32c - GET_BE_DWORD(group->startCharCode);
|
||||
*pgi = GET_BE_DWORD(group->startGlyphID) + offset;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void GSUB_initialize_script_cache(ScriptCache *psc)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -2800,7 +2800,7 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
|
|||
heap_free(rChars);
|
||||
return E_PENDING;
|
||||
}
|
||||
if (CMAP_GetGlyphIndex(hdc, (ScriptCache *)*psc, chInput, &glyph, 0) == GDI_ERROR)
|
||||
if (OpenType_CMAP_GetGlyphIndex(hdc, (ScriptCache *)*psc, chInput, &glyph, 0) == GDI_ERROR)
|
||||
{
|
||||
heap_free(rChars);
|
||||
return S_FALSE;
|
||||
|
|
|
@ -221,4 +221,4 @@ void Indic_ParseSyllables( HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, LPCW
|
|||
|
||||
void BREAK_line(const WCHAR *chars, int count, const SCRIPT_ANALYSIS *sa, SCRIPT_LOGATTR *la) DECLSPEC_HIDDEN;
|
||||
|
||||
DWORD CMAP_GetGlyphIndex(HDC hdc, ScriptCache *psc, DWORD utf32c, LPWORD pgi, DWORD flags) DECLSPEC_HIDDEN;
|
||||
DWORD OpenType_CMAP_GetGlyphIndex(HDC hdc, ScriptCache *psc, DWORD utf32c, LPWORD pgi, DWORD flags) DECLSPEC_HIDDEN;
|
||||
|
|
Loading…
Reference in New Issue