📄 gfx_drawlib.c
字号:
static inline RMstatus rtk86_get_tt_char_size(struct RUA *pRua, RMuint32 char_index, RMuint32 char_size, struct GFXEngine_GlyphMask_type *glyph_param, GFXLib_rect *out_rect){ struct ttf_glyph_metrics *glyph_metrics; struct GFXEngine_GlyphOutputSize_out_type glyph_out; RMstatus err; RMuint16 l; if (!init) { for (l = 0; l < 2048; l++) { width[l] = -1; height[l] = -1; size[l] = -1; } init = TRUE; } if ((RMint32) char_size == size[char_index]) { out_rect->width = width[char_index]; out_rect->height = height[char_index]; glyph_metrics = RMTTGetGlyphMetrics(gdata.ttfont, char_index); if (glyph_metrics == NULL) { RMDBGLOG((ENABLE, "Could not retrieve size( char_index %ld)\n", char_index )); return RM_ERROR; } glyph_param->ScaleFactor = (char_size << 11) / gdata.ttfont->metrics.unitsPerEm; glyph_param->XMin = glyph_metrics->xMin; glyph_param->XMax = glyph_param->XMin + glyph_metrics->advance; glyph_param->YMin = (RMint16) gdata.ttfont->metrics.descender; glyph_param->YMax = gdata.ttfont->metrics.ascender; } else { glyph_metrics = RMTTGetGlyphMetrics(gdata.ttfont, char_index); if (glyph_metrics == NULL) { RMDBGLOG((ENABLE, "Could not retrieve size( char_index %ld)\n", char_index )); return RM_ERROR; } glyph_param->ScaleFactor = (char_size << 11) / gdata.ttfont->metrics.unitsPerEm; glyph_param->XMin = glyph_metrics->xMin; glyph_param->XMax = glyph_param->XMin + glyph_metrics->advance; glyph_param->YMin = (RMint16) gdata.ttfont->metrics.descender; glyph_param->YMax = gdata.ttfont->metrics.ascender; err = RUAExchangeProperty(pRua, gdata.gfx, RMGFXEnginePropertyID_GlyphOutputSize, glyph_param, sizeof(*glyph_param), &glyph_out, sizeof(glyph_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get glyph output size\n")); return err; } out_rect->width = glyph_out.Width; out_rect->height = glyph_out.Height; width[char_index] = glyph_out.Width; height[char_index] = glyph_out.Height; size[char_index] = char_size; } return RM_OK;}static inline RMuint32 RMTTGetCompoundCount(struct RMTTFont *rmfont, RMuint32 char_code){ RMuint32 glyph_index; glyph_index = char_code;/* get_glyph_index(char_code); */ if (glyph_index == INVALID_GLYPH) return 0; /* lets not fool the calling app */ return rmfont->glyph_table[glyph_index].subglyph_count;}static inline struct ttf_scale_matrix *RMTTGetScaleMatrix(struct RMTTFont *rmfont, RMuint32 char_code, RMuint32 index){ RMuint32 glyph_index; struct ttf_subglyph *sub_table; glyph_index = char_code;/* get_glyph_index(char_code); */ if (glyph_index == INVALID_GLYPH) { return NULL; } if (index >= rmfont->glyph_table[glyph_index].subglyph_count) { return NULL; } if (rmfont->glyph_table[glyph_index].size > 0) { return NULL; /* means a simple glyph */ } sub_table = (struct ttf_subglyph *) (rmfont->glyph_table[glyph_index].addr); return &(sub_table[index].scale_matrix);}static inline RMstatus RMTTGetGlyphPointer(struct RMTTFont *rmfont, RMuint32 char_code, RMuint32 index, RMuint32 *addr, RMuint32 *size){ RMuint32 glyph_index; struct ttf_subglyph *sub_table; glyph_index = char_code;/* get_glyph_index(char_code); */ if (glyph_index == INVALID_GLYPH) return RM_INVALID_PARAMETER; if (index >= rmfont->glyph_table[glyph_index].subglyph_count) return RM_INVALID_PARAMETER; if (rmfont->glyph_table[glyph_index].subglyph_count == 0) { *size = 0; *addr = 0; } else if (rmfont->glyph_table[glyph_index].size) { *size = rmfont->glyph_table[glyph_index].size; *addr = rmfont->glyph_table[glyph_index].addr; } else { sub_table = (struct ttf_subglyph *) (rmfont->glyph_table[glyph_index].addr); *size = sub_table[index].size; *addr = sub_table[index].addr; } return RM_OK;}static inline RMstatus GFXColorFormatProperty(struct RUA *pRua, struct GFXEngine_ColorFormat_type *format_param){ RMstatus status; struct RUAEvent evt; RMuint8 trycount; trycount = 2; // try command only a couple of times then jump out tryagain: status = RUASetProperty(pRua, gdata.gfx, RMGFXEnginePropertyID_ColorFormat, format_param, sizeof(struct GFXEngine_ColorFormat_type), 0); if (status == RM_PENDING && trycount--) { evt.ModuleID = gdata.gfx; evt.Mask = RUAEVENT_COMMANDCOMPLETION; if (RUAWaitForMultipleEvents(pRua, &evt, 1, 1000000, NULL) != RM_OK) RMDBGLOG((GFXDBG, "gfxColorFormat: FAILED WAITING FOR 1 second... TIMING ISSUE?\n")); goto tryagain; } return status;}//static inline RMstatus SetTextPaletteOut(// struct RUA *pRua,// RMuint32 foregroundcolor,// RMuint32 backgroundcolor,// RMbool transparentbkgnd)//{// struct GFXEngine_Palette_1BPP_type palette_param;// RMstatus status;//// palette_param.Palette[0] = foregroundcolor;// palette_param.Palette[1] = (transparentbkgnd ? backgroundcolor & 0xffffffff : 0);// palette_param.SurfaceID = GFX_SURFACE_ID_NX;//// if(CompareTextPalette(&palette_param)){//// printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> skipping TEXT palette\n");// return RM_OK;// }////// printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> setting TEXT palette\n");// status = GFX1BPPPaletteProperty(pRua, &palette_param);// if (RMFAILED(status))// RMDBGLOG((GFXDBG, "Error sending command set palette\n"));//// RMMemcpy(&g_lastpal, &palette_param, sizeof(palette_param));// g_last_palbpp = 1;//// return status;//}static inline RMstatus rtk86_draw_tt_char(struct RUA *pRua, RMuint32 char_index, RMuint32 char_size, RMuint32 fg_color, RMuint32 bg_color, Point *point, GFXLib_rect *out_rect){ struct GFXEngine_GlyphMask_type glyph_param; struct ttf_scale_matrix *tt_matrix = NULL; struct GFXEngine_GlyphScaleMatrix_type gfx_matrix; RMstatus err; RMuint32 glyph_size, glyph_addr, compound_cnt, i; out_rect->x = point->x; out_rect->y = point->y; rtk86_get_tt_char_size(pRua, char_index, char_size, &glyph_param, out_rect); // printf("time for char size %llu\n", end - begin); if ((out_rect->x + out_rect->width > gdata.osdWidth) || (out_rect->height + out_rect->y > gdata.osdHeight)) { printf("Failed to write scratch: glyph is outside the osd %d %d\n", (RMint16) (out_rect->x + out_rect->width), (RMint16) (out_rect->height + out_rect->y)); return RM_ERROR; } compound_cnt = RMTTGetCompoundCount(gdata.ttfont, char_index); if (compound_cnt == 0) { return RM_OK; } for (i = 0; i < compound_cnt; i++) { struct GFXEngine_MoveReplaceRectangle_type replace_param; struct GFXEngine_Surface_type surface_param; tt_matrix = RMTTGetScaleMatrix(gdata.ttfont, char_index, i); if (tt_matrix != NULL) { printf("%d, %d, %d, %d, %d, %d\n", tt_matrix->x_scale, tt_matrix->y_scale, tt_matrix->yx_scale, tt_matrix->xy_scale, tt_matrix->x_offset, tt_matrix->y_offset); gfx_matrix.XScale = tt_matrix->x_scale; gfx_matrix.YScale = tt_matrix->y_scale; gfx_matrix.YXScale = tt_matrix->yx_scale; gfx_matrix.XYScale = tt_matrix->xy_scale; gfx_matrix.XOffset = tt_matrix->x_offset; gfx_matrix.YOffset = tt_matrix->y_offset; while ((err = RUASetProperty(pRua, gdata.gfx, RMGFXEnginePropertyID_GlyphScaleMatrix, &gfx_matrix, sizeof(gfx_matrix), 0)) == RM_PENDING) ; if (RMFAILED(err)) { RMDBGLOG((GFXDBG,"Error sending command matrix (char code %ld)\n",char_index)); return RM_ERROR; } } RMTTGetGlyphPointer(gdata.ttfont, char_index, i, &glyph_addr, &glyph_size); if (glyph_addr == 0x0) return RM_ERROR; glyph_param.GlyphAddr = glyph_addr; glyph_param.Size = glyph_size; glyph_param.OutAddr = gdata.drawBuffer.baseAddr; glyph_param.ScaleFactor = (char_size << 11) / gdata.ttfont->metrics.unitsPerEm; while ((err = RUASetProperty(pRua, gdata.gfx, RMGFXEnginePropertyID_GlyphMask, &glyph_param, sizeof(glyph_param), 0)) == RM_PENDING) ; // err = RM_OK; if (RMFAILED(err)) { RMDBGLOG((GFXDBG,"Error sending command glyph (char code %ld)\n", char_index)); return RM_ERROR; } // SetOutputSurfaceBuffer(pRua, gdata.backBuffer.baseAddr, gdata.osdWidth); /*SetTextColorFormat(pRua); SetTextPalette(pRua, fg_color, bg_color, TRUE);*/ surface_param.SurfaceID = GFX_SURFACE_ID_Y; surface_param.StartAddress = gdata.drawBuffer.baseAddr; surface_param.TotalWidth = ((out_rect->width + 0x3f) >> 6) << 6; //printf("text %lu now %lu\n", out_rect->width, ((out_rect->width + 0x3f)>>6)<<6); surface_param.Tiled = FALSE; while ((err = RUASetProperty(pRua, gdata.gfx, RMGFXEnginePropertyID_Surface, &surface_param, sizeof(surface_param), 0)) == RM_PENDING) ; if (RMFAILED(err)) RMDBGLOG((GFXDBG, "Error setting surface parameters\n")); //SetInputSurface(pRua, EMhwlibColorMode_LUT_1BPP, gdata.drawBuffer.baseAddr, ((out_rect->width + 0x3f)>>6)<<6, GFX_SURFACE_ID_Y); replace_param.SrcX = 0; replace_param.SrcY = 0; replace_param.DstX = out_rect->x; replace_param.DstY = out_rect->y; replace_param.Width = RMmax(out_rect->width, 8); replace_param.Height = out_rect->height; replace_param.AlphaX = 0; replace_param.AlphaY = 0; replace_param.Merge = FALSE; while ((err = RUASetProperty(pRua, gdata.gfx, RMGFXEnginePropertyID_ReplaceRectangle, &replace_param, sizeof(replace_param), 0)) == RM_PENDING) ; if (RMFAILED(err)) RMDBGLOG((ENABLE, "Error sending command move\n")); } return RM_OK;}RMstatus gfxGetTextExtents(struct RUA *pRua, Prop *prop, GFXLib_rect *out_rect){ // static RMint8 width[2048]={-1,}; // static RMint8 size[2048]={-1,}; // static RMint8 height[2048]={-1,}; // static RMbool init = FALSE; // RMuint64 begin, end; struct GFXEngine_GlyphMask_type glyph_param; RMuint16 i, l; union { RMuint16 l; RMint8 b[2]; } big; // if(!init) // { // for(l=0; l < 2048; l++) // { // width[l] = -1; // height[l] = -1; // size[l] = -1; // } // // init = TRUE; // } // begin = RMGetTimeInMicroSeconds(); if (out_rect == NULL) return RM_ERROR; out_rect->x = out_rect->y = out_rect->width = out_rect->height = 0; l = RMasciiLength(prop->text); for (i = 0; i < l; i++) { GFXLib_rect char_out_rect; if ((prop->text[i] & 0x80) == 0) { big.l = (RMuint16) prop->text[i]; // RMDBGLOG((GFXDBG, "One Byte \'%c\'\n", prop->text[i])); } else if (prop->text[i] & 0xC0) { RMuint8 _t; _t = prop->text[i]; _t <<= 6; _t &= 0xC0; big.b[0] = (prop->text[i + 1] & 0x3F) | _t; big.b[1] = (prop->text[i] & 0x1f) >> 2; i++; // RMDBGLOG((GFXDBG, "TwoBytes \'%X\'\n", big.l)); } // if(width[big.l] != -1 && (RMint8)prop->scale == size[big.l]) // { // char_out_rect.width = width[big.l]; // char_out_rect.height = height[big.l]; // // } // else // { rtk86_get_tt_char_size(pRua, (RMuint32) big.l, prop->scale, &glyph_param, &char_out_rect); // char_out_rect.width += (prop->scale / 10); // if(prop->scale == subs.sub_size) // { // width[big.l] = char_out_rect.width; // height[big.l] = char_out_rect.height; // size[big.l] = prop->scale; // } // } out_rect->width += char_out_rect.width; if (prop->scale != subs.sub_size) out_rect->width += (prop->scale >> 4); else out_rect->width += 2; if (out_rect->height < char_out_rect.height) out_rect->height = char_out_rect.height; } // end = RMGetTimeInMicroSeconds(); // printf("Time Get text extents %llu\n", end - begin); return RM_OK;}RMstatus gfxTTDrawString(struct RUA *pRua, GFXLib_rect *position, Prop *prop, GFXLib_rect *out_rect){ // RMuint32 fgColor, bgColor, char_size; RMuint16 i, l; RMstatus err = RM_OK; Point pos; GFXLib_rect rctext; RMuint8 inc = 0; RMuint8 filter = 10; // RMbool truncate = FALSE; union { RMuint16 l; RMint8 b[2]; } big; if (position->x >= (RMint32) gdata.osdWidth || position->y >= (RMint32) gdata.osdHeight) { RMDBGLOG((GFXDBG, "Failed to draw string: position is off osd limits\n")); return RM_ERROR; } pos.x = position->x; gfxGetTextExtents(pRua, prop, &rctext); if (prop->alignment == ALIGN_CENTER) { pos.x += ((position->width - rctext.width) >> 1); if (pos.x < position->x + filter) pos.x = position->x; } else if (prop->alignment == ALIGN_RIGHT) { pos.x += ((position->width - rctext.width)); } pos.y = position->y + ((position->height - rctext.height) >> 1); // if(rctext.width >= (position->width >> 3) * 7) // truncate = TRUE; l = RMasciiLength(prop->text); SetTextColorFormat(pRua); SetTextPalette(pRua, prop->fgColor, prop->bgColor, TRUE); for (i = 0; i < l; i++) { GFXLib_rect char_out_rect; if ((prop->text[i] & 0x80) == 0) { err = rtk86_draw_tt_char(pRua, (RMuint32) prop->text[i], prop->scale, prop->fgColor, prop->bgColor, &pos, &char_out_rect); // RMDBGLOG((GFXDBG, "One Byte \'%x\'\n", prop->text[i])); inc = 1; } else if (prop->text[i] & 0xC0) { RMuint8 _t; _t = prop->text[i]; _t <<= 6; _t &= 0xC0; // printf("draw string: %X %X\n", prop->text[i], prop->text[i+1]); big.b[0] = (prop->text[i + 1] & 0x3F) | _t; big.b[1] = (prop->text[i] & 0x1f) >> 2; i++; err = rtk86_draw_tt_char(pRua, (RMuint32) big.l, prop->scale, prop->fgColor, prop->bgColor, &pos, &char_out_rect); inc = 2; // RMDBGLOG((GFXDBG, "TwoBytes \'%X\'\n", big.l)); } else err = 1; if (RMFAILED(err)) { RMDBGLOG((GFXDBG, "The glyph for character \'%x\' could not be drawn\n", prop->text[i])); break; } pos.x += char_out_rect.width; pos.x += (prop->scale >> 4); if (pos.x >= (RMint16) (posi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -