Commit 6311ccfe authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

usp10: Move CMAP functions to opentype.c.

parent 8c1b9a01
...@@ -9,6 +9,7 @@ C_SRCS = \ ...@@ -9,6 +9,7 @@ C_SRCS = \
indicsyllable.c \ indicsyllable.c \
linebreak.c \ linebreak.c \
mirror.c \ mirror.c \
opentype.c \
shape.c \ shape.c \
shaping.c \ shaping.c \
usp10.c usp10.c
......
/*
* 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 { ...@@ -315,37 +315,6 @@ typedef struct {
GDEF_ClassRangeRecord ClassRangeRecord[1]; GDEF_ClassRangeRecord ClassRangeRecord[1];
} GDEF_ClassDefFormat2; } 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 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_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); 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 ...@@ -3606,89 +3575,6 @@ HRESULT SHAPE_CheckFontForRequiredFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANA
return USP_E_SCRIPT_NOT_IN_FONT; 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) static void GSUB_initialize_script_cache(ScriptCache *psc)
{ {
int i; int i;
......
...@@ -2800,7 +2800,7 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc, ...@@ -2800,7 +2800,7 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
heap_free(rChars); heap_free(rChars);
return E_PENDING; 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); heap_free(rChars);
return S_FALSE; return S_FALSE;
......
...@@ -221,4 +221,4 @@ void Indic_ParseSyllables( HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, LPCW ...@@ -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; 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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment