Start to implement InitBasicShapingEngine

This commit is contained in:
Vincent Wei
2019-03-20 18:53:06 +08:00
parent 46a8b1768a
commit c276122f60
5 changed files with 202 additions and 136 deletions
+16 -1
View File
@@ -12176,6 +12176,21 @@ MG_EXPORT int GUIAPI UChars2AChars(LOGFONT* logfont, const Uchar32* ucs,
* from their upright orientation.
*/
#define GRF_TEXT_ORIENTATION_SIDEWAYS 0x01000000
/**
* The glyphs are individually typeset upside down in
* vertical lines with vertical font metrics.
*/
#define GRF_TEXT_ORIENTATION_UPSIDE_DOWN 0x02000000
/**
* The glyphs typeset a run rotated 90° counter-clockwise
* from their upright orientation.
*/
#define GRF_TEXT_ORIENTATION_SIDEWAYS_LEFT 0x03000000
/**
* In vertical writing modes, all typographic character units
* keep in their intrinsic orientation.
*/
#define GRF_TEXT_ORIENTATION_AUTO 0x04000000
/**
* In vertical writing modes, typographic character units from
* horizontal-only scripts are typeset sideways, i.e. 90° clockwise
@@ -12183,7 +12198,7 @@ MG_EXPORT int GUIAPI UChars2AChars(LOGFONT* logfont, const Uchar32* ucs,
* Typographic character units from vertical scripts are
* typeset with their intrinsic orientation.
*/
#define GRF_TEXT_ORIENTATION_MIXED 0x02000000
#define GRF_TEXT_ORIENTATION_MIXED 0x05000000
#define GRF_OVERFLOW_WRAP_MASK 0x00F00000
/**
+87 -2
View File
@@ -3,7 +3,7 @@
* and Graphics User Interface (GUI) support system for embedded systems
* and smart IoT devices.
*
* Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd.
* Copyright (C) 2002~2019, Beijing FMSoft Technologies Co., Ltd.
* Copyright (C) 1998~2002, WEI Yongming
*
* This program is free software: you can redistribute it and/or modify
@@ -35,7 +35,7 @@
/*
** layoutinfo.c: The implementation of APIs related LAYOUTINFO
**
** Create by WEI Yongming at 2019/03/14
** Create by WEI Yongming at 2019/03/20
*/
#include <stdio.h>
@@ -53,6 +53,91 @@
#include "unicode-ops.h"
#include "layoutinfo.h"
LAYOUTINFO* GUIAPI CreateLayoutInfo(
const TEXTRUNSINFO* runinfo, Uint32 render_flags,
const BreakOppo* break_oppos, BOOL persist_lines,
int letter_spacing, int word_spacing, int tab_size)
{
LAYOUTINFO* layoutinfo;
if (runinfo == NULL || runinfo->sei.inst == NULL) {
return NULL;
}
layoutinfo = (LAYOUTINFO*)calloc(1, sizeof(LAYOUTINFO));
if (layoutinfo == NULL) {
return NULL;
}
layoutinfo->runinfo = runinfo;
layoutinfo->bos = break_oppos;
layoutinfo->rf = render_flags;
layoutinfo->ls = letter_spacing;
layoutinfo->ws = word_spacing;
layoutinfo->ts = tab_size;
INIT_LIST_HEAD(&layoutinfo->line_head);
layoutinfo->left_ucs = runinfo->nr_ucs;
layoutinfo->persist = persist_lines ? 1 : 0;
return layoutinfo;
}
static void release_glyph_string(GLYPHSTRING* gs)
{
if (gs->glyphs)
free (gs->glyphs);
if (gs->log_clusters);
free (gs->log_clusters);
free(gs);
}
static void release_run(GLYPHRUN* run)
{
if (run->gs) {
release_glyph_string(run->gs);
}
free(run);
}
static void release_line(LAYOUTLINE* line)
{
while (!list_empty(&line->run_head)) {
GLYPHRUN* run = (GLYPHRUN*)line->run_head.prev;
list_del(line->run_head.prev);
release_run(run);
}
if (line->log_widths) {
free(line->log_widths);
}
free(line);
}
BOOL GUIAPI DestroyLayoutInfo(LAYOUTINFO* info)
{
while (!list_empty(&info->line_head)) {
LAYOUTLINE* line = (LAYOUTLINE*)info->line_head.prev;
list_del(info->line_head.prev);
release_line(line);
}
free(info);
return TRUE;
}
LAYOUTLINE* GUIAPI LayoutNextLine(LAYOUTINFO* info,
LAYOUTLINE* prev_Line,
int* x, int* y, int max_extent, SIZE* line_size,
CB_GLYPH_LAID_OUT cb_laid_out, GHANDLE ctxt)
{
return NULL;
}
#if 0
int GUIAPI DrawShapedGlyphString(HDC hdc,
LOGFONT* logfont_upright, LOGFONT* logfont_sideways,
+15 -13
View File
@@ -3,7 +3,7 @@
* and Graphics User Interface (GUI) support system for embedded systems
* and smart IoT devices.
*
* Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd.
* Copyright (C) 2002~2019, Beijing FMSoft Technologies Co., Ltd.
* Copyright (C) 1998~2002, WEI Yongming
*
* This program is free software: you can redistribute it and/or modify
@@ -57,17 +57,17 @@ struct _SHAPEDGLYPH {
};
struct _GLYPHSTRING {
SHAPEDGLYPH* glyphs;
int* log_clusters;
SHAPEDGLYPH* glyphs;
int* log_clusters;
int nr_glyphs;
int reserved;
int nr_glyphs;
int reserved;
};
struct _GLYPHRUN {
struct list_head list;
TEXTRUN* text_run; // the text run to which this glyph run belongs
GLYPHSTRING* glyphstr; // the glyph string
TEXTRUN* text; // the text run to which this glyph run belongs
GLYPHSTRING* gs; // the glyph string
};
struct _LAYOUTLINE {
@@ -86,19 +86,21 @@ struct _LAYOUTLINE {
Uint8 all_odd:1; // flag indicating all level is odd
};
struct _GLYPHLAYOUTINFO {
struct _LAYOUTINFO {
const TEXTRUNSINFO* runinfo;
const BreakOppo* break_oppos;
const BreakOppo* bos;
Uint32 render_flags;
int letter_spacing;
int word_spacing;
int tab_size;
Uint32 rf;
int ls;
int ws;
int ts;
struct list_head line_head; // the list head of lines
LAYOUTLINE *curr_line; // current line
int left_ucs; // the number of chars not laied out.
Uint32 persist:1; // persist lines?
};
#ifdef __cplusplus
+82 -119
View File
@@ -55,21 +55,7 @@
#include "window.h"
#include "devfont.h"
#include "unicode-ops.h"
#include "textrunsinfo.h"
#if 0
static void bidi_reverse_shaped_glyphs (void* context, int len, int pos)
{
int i;
SHAPEDGLYPH* vgs = (SHAPEDGLYPH*)context + pos;
for (i = 0; i < len / 2; i++) {
SHAPEDGLYPH tmp = vgs[i];
vgs[i] = vgs[len - 1 - i];
vgs[len - 1 - i] = tmp;
}
}
#endif
#include "layoutinfo.h"
/* Local array size, used for stack-based local arrays */
@@ -79,12 +65,25 @@ static void bidi_reverse_shaped_glyphs (void* context, int len, int pos)
# define LOCAL_ARRAY_SIZE 128
#endif
BOOL GUIAPI InitBasicShapingEngine(TEXTRUNSINFO* run_info)
static void reverse_ucs (Uchar32* ucs, int len)
{
#if 0
int ret_value = 0;
int i, j, nr_reordered;
BidiLevel max_level = 0;
int i;
for (i = 0; i < len / 2; i++) {
Uchar32 tmp = ucs[i];
ucs[i] = ucs[len - 1 - i];
ucs[len - 1 - i] = tmp;
}
}
static BOOL shape_text_run(SEINSTANCE* inst,
const TEXTRUNSINFO* info, const TEXTRUN* run,
GLYPHSTRING* gs)
{
BOOL ok = FALSE;
int i, j;
const Uchar32* logical_ucs = info->ucs + run->idx;
int nr_ucs = run->len;
Uchar32 local_visual_ucs[LOCAL_ARRAY_SIZE];
Uchar32* visual_ucs = NULL;
@@ -95,83 +94,48 @@ BOOL GUIAPI InitBasicShapingEngine(TEXTRUNSINFO* run_info)
BidiType local_bidi_ts[LOCAL_ARRAY_SIZE];
BidiType *bidi_ts = NULL;
BidiBracketType local_brk_ts[LOCAL_ARRAY_SIZE];
BidiBracketType *brk_ts = NULL;
BidiLevel local_els[LOCAL_ARRAY_SIZE];
BidiLevel* els = NULL;
int local_indics_map[LOCAL_ARRAY_SIZE];
int* indics_map = NULL;
if (nr_ucs == 0 || logical_ucs == NULL || break_oppos == NULL ||
visual_glyphs == NULL || nr_glyphs == NULL) {
return 0;
}
/* TODO: we may re-use visual_glyphs for visual ucs */
if (nr_ucs < LOCAL_ARRAY_SIZE)
visual_ucs = local_visual_ucs;
else
visual_ucs = malloc (nr_ucs * sizeof(Uchar32));
visual_ucs = malloc(nr_ucs * sizeof(Uchar32));
if (!visual_ucs)
goto out;
if (nr_ucs < LOCAL_ARRAY_SIZE)
indics_map = local_indics_map;
else
indics_map = malloc (nr_ucs * sizeof(int));
if (!indics_map)
goto out;
/* TODO: compose logical character here */
memcpy(visual_ucs, logical_ucs, sizeof(Uchar32) * nr_ucs);
if (nr_ucs < LOCAL_ARRAY_SIZE)
bidi_ts = local_bidi_ts;
else
bidi_ts = malloc (nr_ucs * sizeof(BidiType));
if (!bidi_ts)
goto out;
UStrGetBidiTypes(logical_ucs, nr_ucs, bidi_ts);
if (nr_ucs < LOCAL_ARRAY_SIZE)
brk_ts = local_brk_ts;
else
brk_ts = (BidiBracketType*)malloc (nr_ucs * sizeof(BidiBracketType));
if (!brk_ts)
goto out;
UStrGetBracketTypes (logical_ucs, bidi_ts, nr_ucs, brk_ts);
if (nr_ucs < LOCAL_ARRAY_SIZE)
els = local_els;
else
els = (BidiLevel*)malloc (nr_ucs * sizeof(BidiLevel));
if (!els)
goto out;
max_level = UBidiGetParagraphEmbeddingLevels(bidi_ts, brk_ts, nr_ucs,
paragraph_dir, els) - 1;
if (max_level < 0)
goto out;
// Get the embedding levels from run instead calling
// UBidiGetParagraphEmbeddingLevels
memset(els, run->el, nr_ucs);
/* Set up the ordering array to identity order */
for (i = 0; i < nr_ucs; i++)
indics_map[i] = i;
if (run->st == SCRIPT_ARABIC) {
if (writing_system == SCRIPT_ARABIC) {
/* Arabic joining */
if (nr_ucs < LOCAL_ARRAY_SIZE)
bidi_ts = local_bidi_ts;
else
bidi_ts = malloc (nr_ucs * sizeof(BidiType));
if (!bidi_ts)
goto out;
UStrGetBidiTypes(logical_ucs, nr_ucs, bidi_ts);
/* Arabic joining */
if (run->len < LOCAL_ARRAY_SIZE)
ar_props = local_ar_props;
else
ar_props = malloc(sizeof(BidiArabicProp) * nr_ucs);
ar_props = malloc(sizeof(BidiArabicProp) * run->len);
if (!ar_props)
goto out;
@@ -181,66 +145,64 @@ BOOL GUIAPI InitBasicShapingEngine(TEXTRUNSINFO* run_info)
UBidiShape(BIDI_FLAG_SHAPE_MIRRORING | BIDI_FLAG_SHAPE_ARAB_PRES |
BIDI_FLAG_SHAPE_ARAB_LIGA,
els, nr_ucs, ar_props, visual_ucs);
if (bidi_ts && bidi_ts != local_bidi_ts) {
free (bidi_ts);
bidi_ts = NULL;
}
}
else if (BIDI_LEVEL_IS_RTL(run->el)) {
UBidiShapeMirroring(els, nr_ucs, visual_ucs);
}
if (UBidiReorderLine(BIDI_FLAGS_DEFAULT, bidi_ts, nr_ucs, 0,
*paragraph_dir, els, visual_ucs, indics_map, NULL, NULL) == 0)
if (els && els != local_els) {
free (els);
els = NULL;
}
// reorder visual chars
if (BIDI_LEVEL_IS_RTL(run->el)) {
reverse_ucs(visual_ucs, nr_ucs);
}
// generate the glyphs
gs->glyphs = malloc(sizeof(SHAPEDGLYPH) * nr_ucs);
gs->log_clusters = malloc(sizeof(int) * nr_ucs);
if (gs->glyphs == NULL || gs->log_clusters == NULL)
goto out;
// remove the unused characters and get the real length of the visual ucs.
j = 0;
for (i = 0; i < nr_ucs; i++) {
if (!BIDI_IS_EXPLICIT_OR_BN (bidi_ts[indics_map[i]])) {
visual_ucs[j] = visual_ucs[i];
j++;
}
}
nr_reordered = j;
if (break_oppos) {
// The breaking opportunities
if (UStrGetBreaks(writing_system, ctr, wbr, lbp, visual_ucs, nr_reordered,
&break_oppos) == 0)
goto out;
}
// get shaped glyphs
for (i = 0; i < nr_reordered; i++) {
visual_glyphs[i] = GetGlyphValue(logfont, UCHAR2ACHAR(visual_ucs[i]));
Glyph32 gv;
// check cluster for ligatures and marks
if (ar_props) {
BidiArabicProp ar_prop = ar_props[indics_map[i]];
BidiArabicProp ar_prop = ar_props[i];
if (ar_prop & BIDI_MASK_LIGATURED) {
glyph_shaping_info[i].gt = GLYPH_TYPE_STDLIGATURE;
glyph_shaping_info[i].gp = GLYPH_POS_BASELINE;
}
else if (UCharIsArabicVowel(visual_ucs[i])) {
glyph_shaping_info[i].gt = GLYPH_TYPE_STDMARK;
glyph_shaping_info[i].gp = GLYPH_POS_STDMARK_ABOVE;
}
else {
glyph_shaping_info[i].gt = GLYPH_TYPE_STANDALONE;
glyph_shaping_info[i].gp = GLYPH_POS_BASELINE;
gv = GetGlyphValue(run->lf, UCHAR2ACHAR(visual_ucs[i]));
gs->glyphs[j].gv = gv;
j++;
if (UCharIsArabicVowel(logical_ucs[i])) {
// adjust offset
}
else {
}
}
}
else {
glyph_shaping_info[i].gt = GLYPH_TYPE_STANDALONE;
glyph_shaping_info[i].gp = GLYPH_POS_BASELINE;
}
}
gs->nr_glyphs = j;
if (ar_props && ar_props != local_ar_props) {
free (ar_props);
ar_props = NULL;
}
*nr_glyphs = nr_reordered;
if (map_v2l) {
memcpy(map_v2l, indics_map, sizeof(int) * nr_reordered);
}
ret_value = nr_ucs;
ok = TRUE;
out:
if (indics_map && indics_map != local_indics_map)
free (indics_map);
if (visual_ucs && visual_ucs != local_visual_ucs)
free (visual_ucs);
@@ -253,11 +215,12 @@ out:
if (bidi_ts && bidi_ts != local_bidi_ts)
free (bidi_ts);
if (brk_ts && brk_ts != local_brk_ts)
free (brk_ts);
return ok;
}
return ret_value;
#endif
BOOL GUIAPI InitBasicShapingEngine(TEXTRUNSINFO* info)
{
info->sei.shape = shape_text_run;
return FALSE;
}
+2 -1
View File
@@ -49,7 +49,8 @@ typedef struct _SEINSTANCE SEINSTANCE;
typedef struct _TEXTCOLORMAP TEXTCOLORMAP;
typedef BOOL (*CB_SHAPE_TEXT_RUN)(SEINSTANCE* instance,
const TEXTRUN* run, GLYPHSTRING* gs);
const TEXTRUNSINFO* info, const TEXTRUN* run,
GLYPHSTRING* gs);
typedef BOOL (*CB_DESTROY_INSTANCE)(SEINSTANCE* instance);