2017-12-19 05:11:44 -08:00
|
|
|
#include "evas_common_private.h"
|
2009-09-21 09:08:51 -07:00
|
|
|
#include "evas_private.h"
|
2008-07-21 09:10:48 -07:00
|
|
|
#include "evas_blend_private.h"
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2011-01-30 02:35:37 -08:00
|
|
|
#include "language/evas_bidi_utils.h" /*defines BIDI_SUPPORT if possible */
|
2010-05-21 00:10:45 -07:00
|
|
|
#include "evas_font_private.h" /* for Frame-Queuing support */
|
2009-04-11 06:11:10 -07:00
|
|
|
|
2011-01-30 02:36:39 -08:00
|
|
|
#include "evas_font_ot.h"
|
2017-11-06 18:22:09 -08:00
|
|
|
#include "draw.h"
|
2011-01-30 02:36:39 -08:00
|
|
|
|
2012-05-17 19:16:54 -07:00
|
|
|
struct _Evas_Glyph
|
|
|
|
{
|
|
|
|
RGBA_Font_Glyph *fg;
|
2014-01-12 12:13:00 -08:00
|
|
|
int x, y;
|
2012-05-17 19:16:54 -07:00
|
|
|
FT_UInt idx;
|
|
|
|
};
|
2010-06-13 22:59:23 -07:00
|
|
|
|
2010-05-21 00:10:45 -07:00
|
|
|
EAPI void
|
|
|
|
evas_common_font_draw_init(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-03-19 03:02:02 -07:00
|
|
|
static void *
|
2017-09-25 02:34:22 -07:00
|
|
|
_evas_font_image_new(RGBA_Font_Glyph *fg, int alpha, Evas_Colorspace cspace)
|
2015-03-19 03:02:02 -07:00
|
|
|
{
|
2017-09-25 02:34:22 -07:00
|
|
|
DATA32 *image_data;
|
|
|
|
int src_w, src_h;
|
|
|
|
|
|
|
|
if (!fg) return NULL;
|
|
|
|
|
|
|
|
image_data = (DATA32 *)fg->glyph_out->bitmap.buffer;
|
|
|
|
src_w = fg->glyph_out->bitmap.width;
|
|
|
|
src_h = fg->glyph_out->bitmap.rows;
|
|
|
|
|
|
|
|
return evas_cache_image_data(evas_common_image_cache_get(), src_w, src_h, image_data, alpha, cspace);
|
2015-03-19 03:02:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-09-25 02:34:22 -07:00
|
|
|
_evas_font_image_draw(void *context, void *surface, void *image, RGBA_Font_Glyph *fg, int x, int y, int w, int h, int smooth)
|
2015-03-19 03:02:02 -07:00
|
|
|
{
|
|
|
|
RGBA_Image *im;
|
2017-09-25 02:34:22 -07:00
|
|
|
int src_w, src_h;
|
2015-03-19 03:02:02 -07:00
|
|
|
|
2017-09-25 02:34:22 -07:00
|
|
|
if (!image || !fg) return;
|
2015-03-19 03:02:02 -07:00
|
|
|
im = image;
|
2017-09-25 02:34:22 -07:00
|
|
|
src_w = fg->glyph_out->bitmap.width;
|
|
|
|
src_h = fg->glyph_out->bitmap.rows;
|
2015-03-19 03:02:02 -07:00
|
|
|
|
|
|
|
#ifdef BUILD_PIPE_RENDER
|
|
|
|
if ((eina_cpu_count() > 1))
|
|
|
|
{
|
|
|
|
evas_common_rgba_image_scalecache_prepare((Image_Entry *)(im),
|
|
|
|
surface, context, smooth,
|
2017-09-25 02:34:22 -07:00
|
|
|
0, 0, src_w, src_h,
|
|
|
|
x, y, w, h);
|
2015-03-19 03:02:02 -07:00
|
|
|
|
|
|
|
evas_common_pipe_image_draw(im, surface, context, smooth,
|
2017-09-25 02:34:22 -07:00
|
|
|
0, 0, src_w, src_h,
|
|
|
|
x, y, w, h);
|
2015-03-19 03:02:02 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
evas_common_rgba_image_scalecache_prepare
|
|
|
|
(&im->cache_entry, surface, context, smooth,
|
2017-09-25 02:34:22 -07:00
|
|
|
0, 0, src_w, src_h,
|
|
|
|
x, y, w, h);
|
2015-03-19 03:02:02 -07:00
|
|
|
evas_common_rgba_image_scalecache_do
|
|
|
|
(&im->cache_entry, surface, context, smooth,
|
2017-09-25 02:34:22 -07:00
|
|
|
0, 0, src_w, src_h,
|
|
|
|
x, y, w, h);
|
2015-03-19 03:02:02 -07:00
|
|
|
|
|
|
|
evas_common_cpu_end_opt();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-23 03:50:29 -08:00
|
|
|
/*
|
2011-02-01 04:17:52 -08:00
|
|
|
* BiDi handling: We receive the shaped string + other props from text_props,
|
2010-07-28 05:00:41 -07:00
|
|
|
* we need to reorder it so we'll have the visual string (the way we draw)
|
|
|
|
* and then for kerning we have to switch the order of the kerning query (as the prev
|
|
|
|
* is on the right, and not on the left).
|
|
|
|
*/
|
2013-01-11 11:57:09 -08:00
|
|
|
EAPI Eina_Bool
|
2013-01-10 17:52:46 -08:00
|
|
|
evas_common_font_rgba_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y,
|
2014-01-12 12:13:00 -08:00
|
|
|
Evas_Glyph_Array *glyphs, RGBA_Gfx_Func func EINA_UNUSED, int ext_x, int ext_y, int ext_w,
|
2013-01-10 17:52:46 -08:00
|
|
|
int ext_h, int im_w, int im_h EINA_UNUSED)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2012-12-17 13:27:07 -08:00
|
|
|
Evas_Glyph *glyph;
|
2011-05-02 08:33:38 -07:00
|
|
|
|
2013-01-11 11:57:09 -08:00
|
|
|
if (!glyphs) return EINA_FALSE;
|
|
|
|
if (!glyphs->array) return EINA_FALSE;
|
2011-05-02 02:28:00 -07:00
|
|
|
|
2012-12-17 13:27:07 -08:00
|
|
|
EINA_INARRAY_FOREACH(glyphs->array, glyph)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2011-02-01 04:17:52 -08:00
|
|
|
RGBA_Font_Glyph *fg;
|
2015-03-19 03:02:02 -07:00
|
|
|
int chr_x, chr_y, w, h;
|
2011-05-26 18:44:10 -07:00
|
|
|
|
2012-12-17 13:27:07 -08:00
|
|
|
fg = glyph->fg;
|
2017-09-25 02:34:22 -07:00
|
|
|
|
2015-03-19 03:02:02 -07:00
|
|
|
w = fg->glyph_out->bitmap.width;
|
|
|
|
h = fg->glyph_out->bitmap.rows;
|
|
|
|
|
2017-09-25 02:34:22 -07:00
|
|
|
if (FT_HAS_FIXED_SIZES(fg->fi->src->ft.face))
|
|
|
|
{
|
|
|
|
if ((fg->fi->bitmap_scalable & EFL_TEXT_FONT_BITMAP_SCALABLE_COLOR) &&
|
|
|
|
FT_HAS_COLOR(fg->fi->src->ft.face))
|
|
|
|
{
|
evas_text: reduce Video Memory & RAM needed for text textures (Color Glyphs)
Summary:
Texture created for bitmap font glyph, with a fixed size in the font, this size could be much bigger than the needed size in application.
Then a scale factor is applied to these textures when drawn.
Now, instead, we will create smaller bitmaps and create texture from them with reduced texture size (that is not needed).
** This will affect both Video Memory and Ram needed to store glyphs**
Open this file {F3883874} in terminology before and after applying the patch and notice the difference.
Test Plan:
**Notes**
- You need to scroll down to make all glyphs visible, then notice Video/Ram memory
| | Video | Ram
|----------------------|-------|-----
| Before (Font_size=50) | 360 | 300
| After (Font_size=50) | 40 | 100
| Ration After/before | 11% | 33%
**I notice speed up in text rendering for small font size**
```
#include <Elementary.h>
typedef struct _APP
{
Evas_Object *tb1;
Evas_Object *btnLoad;
} APP;
char *text = "<align=center><color=#4DE0FFFF underline=on underline_color=#4DE0FFFF><a href='tel:1234567890'>1234567890</a></color>😀😁😂🤣😃😄😅😆😉😊😋😎😍😘😗😙😚☺🙂🤗🤔😐😑😶🙄😏😣😥😮🤐😯😪😫😴😌🤓😛😜😝🤤😒😓😔😕🙃🤑😲☹🙁😖😞😟😤😢😭😦😧😨😩😬😰😱😳😵😡😠😇🤠🤡🤥😷🤒🤕🤢🤧☻😈👿👹👺💀☠👻👽👾🤖💩😺😸😹😻😼😽🙀😿😾🙈🙉🙊👦👧👨👩👵👶👼👨⚕️👩⚕️👨🎓👩🎓👨🏫👩🏫👨⚖👩⚖👨🌾👩🌾👨🍳👩🍳👨🔧👩🔧👨🏭👩🏭👨💼👩💼👨🔬👩🔬👨💻👩💻👨🎤👩🎤👨🎨👩🎨👨✈️👩✈️👨🚀👩🚀👨🚒👩🚒👮♂️👮♀️🕵️♂️🕵️♀️💂♂️💂♀️👷♂️👷♀️👳♂️👳♀️👱♂️👱♀️🎅🤶👸🤴👰🤵🤰👲🙍♂️🙍♀️🙎♂️🙎♀️🙅♂️🙅♀️🙆♂️🙆♀️💁♂️💁♀️🙋♂️🙋♀️🙇♂️🙇♀️🤦♂️🤦♀️🤷♂️🤷♀️💆♂️💆♀️💇♂️💇♀️🚶♂️🚶♀️🏃♂️🏃♀️💃🕺👯♂️👯♀️🕴🗣👤👥👫👬👭💏💑👪👨👩👧👨👩👧👦👨👩👦👦👨👩👧👧👨👦👨👦👦👨👧👨👧👦👨👧👧👩👦👩👦👦👩👧👩👧👦👩👧👧💪🤳👈👉☝️👆🖕👇✌🤞🖖🤘👊🖐✋👌👍👎✊👊🤛🤜🤚👋👏✍👐🙌🙏🤝💅👂👃👣👀👁👅👄💋💘❤💓💔💕💖💗💙💚💛💜🖤💝💞💟❣💌💤💢💣💥💦💨💫💬🗨🗯💭🕳👓🕶👔👕👖👗👘👙👚👛👜👝🛍🎒👞👟👠👡👢👑👒🎩🎓⛑📿💄💍💎🐵🐒🦍🐶🐕🐩🐺🦊🐱🐈🦁🐯🐅🐆🐴🐎🦌🦄🐮🐂🐃🐄🐷🐖🐗🐽🐏🐑🐐🐪🐫🐘🦏🐭🐁🐀🐹🐰🐇🐿🦇🐻🐨🐼🐾🦃🐔🐓🐣🐤🐥🐦🐧🕊🦅🦆🦉🐸🐊🐢🦎🐍🐲🐉🐳🐋🐬🐟🐠🐡🦈🐙🐚🦀🦐🦑🦋🐌🐛🐜🐝🐞🕷🕸🦂💐🌸💮🏵🌹🥀🌺🌻🌼🌷⚘🌱🌲🌳🌴🌵🌾🌿☘🍀🍁🍂🍃🍇🍈🍉🍊🍋🍌🍍🍎🍏🍐🍑🍒🍓🍅🥝🥑🍆🥔🥕🌽🌶🥒🍄🥜🌰🍞🥐🥖🥞🧀🍖🍗🥓🍔🍟🍕🌭🌮🌯🥙🥚🍳🥘🍲🥗🍿🍱🍘🍙🍚🍛🍜🍝🍠🍢🍣🍤🍥🍡🍦🍧🍨🍩🍪🎂🍰🍫🍬🍭🍮🍯🍼🥛☕🍵🍶🍾🍷🍸🍹🍺🍻🥂🍽🍴🥄🔪🏺🎃🎄🎆🎇✨🎈🎉🎊🎋🎍🎎🎏🎐🎑🎀🎁🎗🎟🎫🎖🏆🏅🥇🥈🥉⚽️⚾️🏀🏐🏈🏉🎾🎱🎳🏏🏑🏒🏓🏸🥊🥋🥅🎯⛳🏌️♂️🏌️♀️⛸🎣🎽🎿⛷🏂🏄♂️🏄♀️🏇🏊♂️🏊♀️⛹️♂️⛹️♀️🏋️♂️🏋️♀️🚴♂️🚴♀️🚵♂️🚵♀️🏎🏍🤸♂️🤸♀️🤼♂️🤼♀️🤽♂️🤽♀️🤾♂️🤾♀️🤺🤹♂️🤹♀️🎮🕹🎲♠️♥️♦️♣️🃏🀄🎴🌍🌎🌏🌐🗺🏔⛰🌋🗻🏕🏖🏜🏝🏞🏟🏛🏗🏘🏙🏚🏠🏡🏢🏣🏤🏥🏦🏨🏩🏪🏫🏬🏭🏯🏰💒🗼🗽⛪🕌🕍⛩🕋⛲⛺🌁🌃🌄🌅🌆🌇🌉⛼♨️🌌🎠🎡🎢💈🎪🎭🖼🎨🎰🚂🚃🚄🚅🚆🚇🚈🚉🚊🚝🚞🚋🚌🚍🚎🚐🚑🚒🚓🚔🚕🚖🚗🚘🚙🚚🚛⛟🚜🚲🛴🛵🚏🛣🛤⛽🚨🚥🚦🚧🛑⚓⛵🚣♂️🚣♀️🛶🚤🛳⛴🛥🚢✈🛩🛫🛬💺🚁🚟🚠🚡🚀🛰🛎🚪🛌🛏🛋🚽🚿🛀🛁⌛⏳⌚⏰⏱⏲🕰🕛🕧🕐🕜🕑🕝🕒🕞🕓🕟🕔🕠🕕🕡🕖🕢🕗🕣🕘🕤🕙🕥🕚🕦🌑🌒🌓🌔🌕🌖🌗🌘🌙🌚🌛🌜🌡☀️🌝🌞⭐🌟🌠☁️⛅⛈🌤🌥🌦🌧🌨🌩🌪🌫🌬🌀🌈🌂☂️☔⛱⚡❄☃️⛄☄🔥💧🌊🔇🔈🔉🔊📢📣📯🔔🔕🎼🎵🎶🎙🎚🎛🎤🎧📻🎷🎸🎹🎺🎻🥁📱📲☎️📞📟📠🔋🔌💻🖥🖨⌨🖱🖲💽💾💿📀🎥🎞📽🎬📺📷📸📹📼🔍🔎🔬🔭📡🕯💡🔦🏮📔📕📖📗📘📙📚📓📒📃📜📄📰🗞📑🔖🏷💰💴💵💶💷💸💳💱💲✉📧📨📩📤📥📦📫📪📬📭📮🗳✏✒🖋🖊🖌🖍📝💼📁📂🗂📅📆🗒🗓📇📈📉📊📋📌📍📎🖇📏📐✂️🗃🗄🗑🔒🔓🔏🔐🔑🗝🔨⛏⚒🛠🗡⚔🔫🏹🛡🔧🔩⚙🗜⚗⚖🔗⛓💉💊🚬⚰⚱🗿🛢🔮🔮🏧🚮🚰♿🚹🚺🚻🚼🚾🛂🛃🛄🛅⚠️🚸⛔🚫🚳🚭🚯🚱🚷📵🔞☢☣⬆️↗️➡️↘️⬇️↙️⬅️↖️↕️↔️↩↪⤴️⤵️🔃🔄🔙🔚🔛🔜🔝🛐⚛🕉✡☸☯️☦☮🕎🔯♈♉♊♋♌♍♎♏♐♑♒♓⛎🔀🔁🔂▶️⏩⏭⏯◀️⏪⏮🔼⏫🔽⏬⏸⏹⏺⏏🎦🔅🔆📶📳📴♻️📛⚜🔰🔱⭕✅☑✔✖❌❎➕♀️♂️⚕➖➗➰➿〽✳✴❇⁉️❓❔❕❗〰🔟💯🔠🔡🔢🔣🔤🅰️🆎️🅱️🆑️🆒️🆓️ℹ🆔️Ⓜ️🆕️🆖️🅾️🆗️🅿️🆘️🆙️🆚️🈁🈂🈷🈶🈯🉐🈹🈚🈲🉑🈸🈴🈳㊗㊙🈺🈵▫️◻◼◽◾⬛⬜🔶️🔷️🔸️🔹️🔺️🔻💠🔘🔲🔳⚪⚫🔴🔵🏁🚩🏴🏳🏳️🌈⚀⚁⚂⚃⚄⚅⛾♾🇦🇨🇦🇩🇦🇪🇦🇫🇦🇬🇦🇮🇦🇱🇦🇲🇦🇴🇦🇶🇦🇷🇦🇸🇦🇹🇦🇺🇦🇼🇦🇽🇦🇿🇧🇦🇧🇧🇧🇩🇧🇪🇧🇫🇧🇬🇧🇭🇧🇮🇧🇯🇧🇱🇧🇲🇧🇳🇧🇴🇧🇶🇧🇷🇧🇸🇧🇹🇧🇼🇧🇾🇧🇿🇨🇦🇨🇨🇨🇩🇨🇫🇨🇬🇨🇭🇨🇮🇨🇰🇨🇱🇨🇲🇨🇳🇨🇴🇨🇷🇨🇺🇨🇻🇨🇼🇨🇽🇨🇾🇨🇿🇩🇪🇩🇯🇩🇰🇩🇲🇩🇴🇩🇿🇪🇨🇪🇪🇪🇬🇪🇭🇪🇷🇪🇸🇪🇹🇪🇺🇫🇮🇫🇯🇫🇰🇫🇲🇫🇴🇫🇷🇬🇦🇬🇧🇬🇩🇬🇪🇬🇫🇬🇬🇬🇭🇬🇮🇬🇱🇬🇲🇬🇳🇬🇵🇬🇶🇬🇷🇬🇸🇬🇹🇬🇺🇬🇼🇬🇾🇭🇰🇭🇲🇭🇳🇭🇷🇭🇹🇭🇺🇮🇨🇮🇩🇮🇪🇮🇱🇮🇲🇮🇳🇮🇴🇮🇶🇮🇷🇮🇸🇮🇹🇯🇪🇯🇲🇯🇴🇯🇵🇰🇪🇰🇬🇰🇭🇰🇮🇰🇲🇰🇳🇰🇵🇰🇷🇰🇼🇰🇾🇰🇿🇱🇦🇱🇧🇱🇨🇱🇮🇱🇰🇱🇷🇱🇸🇱🇹🇱🇺🇱🇻🇱🇾🇲🇦🇲🇨🇲🇩🇲🇪🇲🇬🇲🇭🇲🇰🇲🇱🇲🇲🇲🇳🇲🇴🇲🇵🇲🇶🇲🇷🇲🇸🇲🇹🇲🇺🇲🇻🇲🇼🇲🇽🇲🇾🇲🇿🇳🇦🇳🇨🇳🇪🇳🇫🇳🇬🇳🇮🇳🇱🇳🇴🇳🇵🇳🇷🇳🇺🇳🇿🇴🇲🇵🇦🇵🇪🇵🇫🇵🇬🇵🇭🇵🇰🇵🇱🇵🇲🇵🇳🇵🇷🇵🇸🇵🇹🇵🇼🇵🇾🇶🇦🇷🇪🇷🇴🇷🇸🇷🇺🇷🇼🇸🇦🇸🇧🇸🇨🇸🇩🇸🇪🇸🇬🇸🇭🇸🇮🇸🇰🇸🇱🇸🇲🇸🇳🇸🇴🇸🇷🇸🇸🇸🇹🇸🇻🇸🇽🇸🇾🇸🇿🇹🇦🇹🇨🇹🇩🇹🇫🇹🇬🇹🇭🇹🇯🇹🇰🇹🇱🇹🇲🇹🇳🇹🇴🇹🇷🇹🇹🇹🇻🇹🇼🇹🇿🇺🇦🇺🇬🇺🇳🇺🇸🇺🇾🇺🇿🇻🇦🇻🇨🇻🇪🇻🇬🇻🇮🇻🇳🇻🇺🇼🇫🇼🇸🇽🇰🇾🇪🇾🇹🇿🇦🇿🇲🇿🇼8<br/><br/><br/><br/>Sent from my Samsung Galaxy smartphone.</align>";
int font_size = 100;
void _button_clicked(void *data, Evas_Object *obj, void *event_info)
{
APP *app = data;
font_size = font_size - font_size/5;
char buffer[100] = {0};
sprintf(buffer, "DEFAULT='font=NotoColorEmoji font_size=%i color=red ellipsis=-1.0 wrap=mixed'", font_size);
Evas_Textblock_Style *style = evas_textblock_style_new();
evas_textblock_style_set(style, buffer);
evas_object_textblock_style_set(app->tb1, style);
evas_textblock_style_free(style);
sprintf(buffer, "font_size = %i",font_size);
elm_object_text_set(app->btnLoad, buffer);
style = NULL;
}
EAPI_MAIN int
elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
{
APP *app = calloc(1, sizeof(APP));
Evas_Object *win, *scroller1, *scroller2, *box;
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
win = elm_win_util_standard_add("", "");
elm_win_autodel_set(win, EINA_TRUE);
box = elm_box_add(win);
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
scroller1 = elm_scroller_add(win);
evas_object_size_hint_weight_set(scroller1, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(scroller1, EVAS_HINT_FILL, EVAS_HINT_FILL);
//evas_text_cache_policy_set(EVAS_TEXT_CACHE_POLICY_TEXTURE ,EVAS_TEXT_CACHE_NONE);
app->tb1 = evas_object_textblock_add(win);
Evas_Textblock_Style *style = evas_textblock_style_new();
char buffer[100] = {0};
sprintf(buffer, "DEFAULT='font=NotoColorEmoji font_size=%i color=red ellipsis=-1.0 wrap=mixed'", font_size);
evas_textblock_style_set(style, buffer);
evas_object_textblock_style_set(app->tb1, style);
evas_textblock_style_free(style);
style = NULL;
int w,h;
evas_object_textblock_text_markup_set(app->tb1, "");
evas_object_size_hint_min_set(app->tb1, 360, 720);
elm_object_content_set(scroller1, app->tb1);
elm_box_pack_end(box, scroller1);
elm_object_content_set(win, box);
app->btnLoad = elm_button_add(win);
sprintf(buffer, "font_size = %i",font_size);
elm_object_text_set(app->btnLoad, buffer);
evas_object_smart_callback_add(app->btnLoad, "clicked", _button_clicked, app);
evas_object_show(app->btnLoad);
evas_object_move(app->btnLoad, 0, 20);
evas_object_resize(app->btnLoad, 150, 20);
evas_object_textblock_text_markup_set(app->tb1, text);
evas_object_textblock_size_formatted_get(app->tb1, &w, &h);
evas_object_size_hint_min_set(app->tb1, 800, w/800 + h + 150);
evas_object_resize(win, 800, 800);
evas_object_show(box);
evas_object_show(scroller1);
evas_object_show(scroller2);
evas_object_show(win);
elm_run();
return 0;
}
ELM_MAIN()
```
Reviewers: raster, woohyun, bu5hm4n, zmike, Hermet, segfaultxavi
Subscribers: cedric, #reviewers, #committers
Tags: #efl
Maniphest Tasks: T8712
Differential Revision: https://phab.enlightenment.org/D11814
2020-05-29 02:10:28 -07:00
|
|
|
if ( !fg->fi->is_resized )
|
|
|
|
{
|
|
|
|
w *= fg->fi->scale_factor;
|
|
|
|
h *= fg->fi->scale_factor;
|
|
|
|
}
|
|
|
|
|
2017-09-25 02:34:22 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-12 12:13:00 -08:00
|
|
|
if ((!fg->ext_dat) && (dc->font_ext.func.gl_new))
|
2011-02-01 04:17:52 -08:00
|
|
|
{
|
|
|
|
/* extension calls */
|
|
|
|
fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg);
|
|
|
|
fg->ext_dat_free = dc->font_ext.func.gl_free;
|
|
|
|
}
|
2015-03-19 03:02:02 -07:00
|
|
|
|
2019-08-20 16:30:23 -07:00
|
|
|
if (dc->font_ext.func.gl_image_new)
|
2015-03-19 03:02:02 -07:00
|
|
|
{
|
2019-08-20 16:30:23 -07:00
|
|
|
if ((!fg->ext_dat) && FT_HAS_COLOR(fg->fi->src->ft.face))
|
2015-03-19 03:02:02 -07:00
|
|
|
{
|
|
|
|
/* extension calls */
|
2017-03-08 02:33:15 -08:00
|
|
|
fg->ext_dat = dc->font_ext.func.gl_image_new
|
|
|
|
(dc->font_ext.data, fg, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
|
2015-03-19 03:02:02 -07:00
|
|
|
fg->ext_dat_free = dc->font_ext.func.gl_image_free;
|
|
|
|
}
|
2019-08-20 16:30:23 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((!fg->col_dat) && FT_HAS_COLOR(fg->fi->src->ft.face))
|
2015-03-19 03:02:02 -07:00
|
|
|
{
|
2019-08-20 16:30:23 -07:00
|
|
|
fg->col_dat = _evas_font_image_new(fg, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
|
2015-03-19 03:02:02 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-12 12:13:00 -08:00
|
|
|
chr_x = x + glyph->x;
|
|
|
|
chr_y = y + glyph->y;
|
2011-02-01 04:17:52 -08:00
|
|
|
if (chr_x < (ext_x + ext_w))
|
|
|
|
{
|
2014-01-12 12:13:00 -08:00
|
|
|
if ((w > 0) && ((chr_x + w) > ext_x))
|
2010-10-07 14:07:53 -07:00
|
|
|
{
|
2015-03-19 03:02:02 -07:00
|
|
|
if (fg->glyph_out->rle)
|
|
|
|
{
|
|
|
|
if ((fg->ext_dat) && (dc->font_ext.func.gl_draw))
|
2015-05-18 01:13:38 -07:00
|
|
|
dc->font_ext.func.gl_draw(dc->font_ext.data, dst,
|
|
|
|
dc, fg,
|
2017-09-25 02:34:22 -07:00
|
|
|
chr_x, y - (chr_y - y), w, h);
|
2015-03-19 03:02:02 -07:00
|
|
|
else
|
2017-09-25 02:34:22 -07:00
|
|
|
// TODO: scale with evas_font_compress_draw.c...
|
2015-05-18 01:13:38 -07:00
|
|
|
evas_common_font_glyph_draw(fg, dc, dst, im_w,
|
2017-09-25 02:34:22 -07:00
|
|
|
chr_x, y - (chr_y - y), w, h,
|
2015-05-18 01:13:38 -07:00
|
|
|
ext_x, ext_y,
|
|
|
|
ext_w, ext_h);
|
2015-03-19 03:02:02 -07:00
|
|
|
}
|
2019-08-20 16:30:23 -07:00
|
|
|
else if (FT_HAS_COLOR(fg->fi->src->ft.face))
|
2015-03-19 03:02:02 -07:00
|
|
|
{
|
2019-08-20 16:30:23 -07:00
|
|
|
if ((fg->ext_dat) && (dc->font_ext.func.gl_image_draw))
|
2015-05-18 01:13:38 -07:00
|
|
|
dc->font_ext.func.gl_image_draw
|
2017-03-08 02:33:15 -08:00
|
|
|
(dc->font_ext.data, fg->ext_dat,
|
2015-05-18 01:13:38 -07:00
|
|
|
chr_x, y - (chr_y - y), w, h, EINA_TRUE);
|
2019-08-20 16:30:23 -07:00
|
|
|
else if (fg->col_dat)
|
2015-05-18 01:13:38 -07:00
|
|
|
_evas_font_image_draw
|
2019-08-20 16:30:23 -07:00
|
|
|
(dc, dst, fg->col_dat, fg,
|
2015-05-18 01:13:38 -07:00
|
|
|
chr_x, y - (chr_y - y), w, h, EINA_TRUE);
|
2015-03-19 03:02:02 -07:00
|
|
|
}
|
2010-10-07 14:07:53 -07:00
|
|
|
}
|
|
|
|
}
|
2011-02-01 04:17:52 -08:00
|
|
|
else
|
|
|
|
break;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2013-01-11 11:57:09 -08:00
|
|
|
|
|
|
|
return EINA_TRUE;
|
2009-02-20 19:13:49 -08:00
|
|
|
}
|
|
|
|
|
2012-12-17 13:27:07 -08:00
|
|
|
void
|
|
|
|
evas_common_font_glyphs_ref(Evas_Glyph_Array *array)
|
|
|
|
{
|
|
|
|
array->refcount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_common_font_glyphs_unref(Evas_Glyph_Array *array)
|
|
|
|
{
|
2013-01-11 11:48:28 -08:00
|
|
|
if (--array->refcount) return;
|
2012-12-17 13:27:07 -08:00
|
|
|
|
|
|
|
eina_inarray_free(array->array);
|
2013-06-14 03:55:53 -07:00
|
|
|
evas_common_font_int_unref(array->fi);
|
2012-12-17 13:27:07 -08:00
|
|
|
free(array);
|
|
|
|
}
|
|
|
|
|
2013-01-15 09:35:11 -08:00
|
|
|
void
|
|
|
|
evas_common_font_fonts_ref(Evas_Font_Array *array)
|
|
|
|
{
|
|
|
|
array->refcount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_common_font_fonts_unref(Evas_Font_Array *array)
|
|
|
|
{
|
|
|
|
if (--array->refcount) return;
|
|
|
|
|
|
|
|
eina_inarray_free(array->array);
|
|
|
|
free(array);
|
|
|
|
}
|
|
|
|
|
2012-04-26 01:18:51 -07:00
|
|
|
EAPI void
|
2012-05-10 18:50:40 -07:00
|
|
|
evas_common_font_draw_prepare(Evas_Text_Props *text_props)
|
2012-04-26 01:18:51 -07:00
|
|
|
{
|
|
|
|
RGBA_Font_Int *fi;
|
2013-07-01 23:18:19 -07:00
|
|
|
RGBA_Font_Glyph *fg = NULL;
|
2012-12-17 13:27:07 -08:00
|
|
|
Eina_Inarray *glyphs;
|
2012-12-23 03:02:50 -08:00
|
|
|
size_t unit = 32;
|
2013-01-11 11:49:15 -08:00
|
|
|
Eina_Bool reused_glyphs;
|
2012-04-26 01:18:51 -07:00
|
|
|
EVAS_FONT_WALK_TEXT_INIT();
|
|
|
|
|
|
|
|
fi = text_props->font_instance;
|
|
|
|
if (!fi) return;
|
|
|
|
|
2015-05-18 01:13:38 -07:00
|
|
|
if ((!text_props->changed) &&
|
|
|
|
(text_props->generation == fi->generation) &&
|
|
|
|
text_props->glyphs)
|
2012-12-17 13:27:07 -08:00
|
|
|
return;
|
2012-05-17 19:16:54 -07:00
|
|
|
|
2012-12-23 03:02:50 -08:00
|
|
|
if (text_props->len < unit) unit = text_props->len;
|
2013-01-11 11:49:15 -08:00
|
|
|
if (text_props->glyphs && text_props->glyphs->refcount == 1)
|
|
|
|
{
|
|
|
|
glyphs = text_props->glyphs->array;
|
|
|
|
glyphs->len = 0;
|
|
|
|
reused_glyphs = EINA_TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
glyphs = eina_inarray_new(sizeof(Evas_Glyph), unit);
|
|
|
|
reused_glyphs = EINA_FALSE;
|
|
|
|
}
|
2012-04-26 01:18:51 -07:00
|
|
|
evas_common_font_int_reload(fi);
|
|
|
|
|
2012-05-30 01:29:29 -07:00
|
|
|
if (fi->src->current_size != fi->size)
|
2012-04-26 01:18:51 -07:00
|
|
|
{
|
2012-05-17 19:16:54 -07:00
|
|
|
evas_common_font_source_reload(fi->src);
|
2012-04-26 01:18:51 -07:00
|
|
|
FTLOCK();
|
|
|
|
FT_Activate_Size(fi->ft.size);
|
|
|
|
FTUNLOCK();
|
|
|
|
fi->src->current_size = fi->size;
|
|
|
|
}
|
|
|
|
|
|
|
|
EVAS_FONT_WALK_TEXT_START()
|
|
|
|
{
|
2013-01-15 22:31:32 -08:00
|
|
|
Evas_Glyph *glyph;
|
2012-05-17 19:16:54 -07:00
|
|
|
FT_UInt idx;
|
2012-04-26 01:18:51 -07:00
|
|
|
|
|
|
|
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
|
|
|
|
idx = EVAS_FONT_WALK_INDEX;
|
|
|
|
|
|
|
|
fg = evas_common_font_int_cache_glyph_get(fi, idx);
|
2012-05-15 14:15:08 -07:00
|
|
|
if (!fg) continue;
|
2013-10-09 17:26:42 -07:00
|
|
|
if (!evas_common_font_int_cache_glyph_render(fg))
|
|
|
|
{
|
|
|
|
fg = NULL;
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2015-05-18 01:13:38 -07:00
|
|
|
glyph = eina_inarray_grow(glyphs, 1);
|
|
|
|
if (!glyph) goto error;
|
2013-01-15 22:31:32 -08:00
|
|
|
|
|
|
|
glyph->fg = fg;
|
|
|
|
glyph->idx = idx;
|
2014-01-12 12:13:00 -08:00
|
|
|
glyph->x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
|
|
|
|
glyph->y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
|
2012-04-26 01:18:51 -07:00
|
|
|
}
|
|
|
|
EVAS_FONT_WALK_TEXT_END();
|
2012-05-10 18:50:40 -07:00
|
|
|
|
2013-01-11 11:49:15 -08:00
|
|
|
if (!reused_glyphs)
|
|
|
|
{
|
2013-01-11 11:56:49 -08:00
|
|
|
if (text_props->glyphs) evas_common_font_glyphs_unref(text_props->glyphs);
|
2013-01-11 11:49:15 -08:00
|
|
|
|
|
|
|
text_props->glyphs = malloc(sizeof(*text_props->glyphs));
|
|
|
|
if (!text_props->glyphs) goto error;
|
2013-10-09 17:26:42 -07:00
|
|
|
text_props->glyphs->refcount = 1;
|
2013-01-11 11:49:15 -08:00
|
|
|
text_props->glyphs->array = glyphs;
|
2013-06-14 03:55:53 -07:00
|
|
|
text_props->glyphs->fi = fi;
|
|
|
|
fi->references++;
|
2013-01-11 11:49:15 -08:00
|
|
|
}
|
2012-12-17 13:27:07 -08:00
|
|
|
|
2012-06-22 13:31:31 -07:00
|
|
|
/* check if there's a request queue in fi, if so ask cserve2 to render
|
|
|
|
* those glyphs
|
|
|
|
*/
|
|
|
|
|
2012-05-10 18:50:40 -07:00
|
|
|
text_props->generation = fi->generation;
|
2013-01-17 02:28:18 -08:00
|
|
|
text_props->changed = EINA_FALSE;
|
2012-12-17 13:27:07 -08:00
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
|
|
|
eina_inarray_free(glyphs);
|
2012-04-26 01:18:51 -07:00
|
|
|
}
|
|
|
|
|
2013-01-11 11:57:09 -08:00
|
|
|
EAPI Eina_Bool
|
2012-12-17 13:27:07 -08:00
|
|
|
evas_common_font_draw_cb(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, Evas_Glyph_Array *glyphs, Evas_Common_Font_Draw_Cb cb)
|
2009-02-20 19:13:49 -08:00
|
|
|
{
|
|
|
|
int ext_x, ext_y, ext_w, ext_h;
|
|
|
|
int im_w, im_h;
|
2009-04-23 21:35:52 -07:00
|
|
|
RGBA_Gfx_Func func;
|
2009-02-20 19:13:49 -08:00
|
|
|
Cutout_Rect *r;
|
2010-10-07 14:07:53 -07:00
|
|
|
int c, cx, cy, cw, ch;
|
|
|
|
int i;
|
2009-04-23 21:35:52 -07:00
|
|
|
|
2013-01-11 11:57:09 -08:00
|
|
|
if (!glyphs) return EINA_FALSE;
|
2013-01-11 11:56:32 -08:00
|
|
|
|
2009-02-20 19:13:49 -08:00
|
|
|
im_w = dst->cache_entry.w;
|
|
|
|
im_h = dst->cache_entry.h;
|
|
|
|
|
2010-02-03 03:18:00 -08:00
|
|
|
// evas_common_font_size_use(fn);
|
2014-11-12 18:27:50 -08:00
|
|
|
func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst->cache_entry.flags.alpha, 1, dc->render_op);
|
2009-02-20 19:13:49 -08:00
|
|
|
|
|
|
|
if (!dc->cutout.rects)
|
|
|
|
{
|
2013-01-10 21:21:54 -08:00
|
|
|
ext_x = 0; ext_y = 0; ext_w = im_w; ext_h = im_h;
|
|
|
|
if (dc->clip.use)
|
|
|
|
{
|
|
|
|
ext_x = dc->clip.x;
|
|
|
|
ext_y = dc->clip.y;
|
|
|
|
ext_w = dc->clip.w;
|
|
|
|
ext_h = dc->clip.h;
|
|
|
|
if (ext_x < 0)
|
|
|
|
{
|
|
|
|
ext_w += ext_x;
|
|
|
|
ext_x = 0;
|
|
|
|
}
|
|
|
|
if (ext_y < 0)
|
|
|
|
{
|
|
|
|
ext_h += ext_y;
|
|
|
|
ext_y = 0;
|
|
|
|
}
|
|
|
|
if ((ext_x + ext_w) > im_w)
|
|
|
|
ext_w = im_w - ext_x;
|
|
|
|
if ((ext_y + ext_h) > im_h)
|
|
|
|
ext_h = im_h - ext_y;
|
|
|
|
}
|
2013-01-11 11:57:09 -08:00
|
|
|
if (ext_w <= 0) return EINA_FALSE;
|
|
|
|
if (ext_h <= 0) return EINA_FALSE;
|
2013-01-10 21:21:54 -08:00
|
|
|
|
2013-01-11 11:57:09 -08:00
|
|
|
return cb(dst, dc, x, y, glyphs,
|
|
|
|
func, ext_x, ext_y, ext_w, ext_h,
|
|
|
|
im_w, im_h);
|
2009-02-20 19:13:49 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-01-11 11:57:09 -08:00
|
|
|
Eina_Bool ret = EINA_FALSE;
|
2009-02-22 23:20:21 -08:00
|
|
|
c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h;
|
2009-02-20 19:13:49 -08:00
|
|
|
evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
|
|
|
|
/* our clip is 0 size.. abort */
|
|
|
|
if ((dc->clip.w > 0) && (dc->clip.h > 0))
|
|
|
|
{
|
2016-11-16 16:05:56 -08:00
|
|
|
dc->cache.rects = evas_common_draw_context_apply_cutouts(dc, dc->cache.rects);
|
|
|
|
for (i = 0; i < dc->cache.rects->active; ++i)
|
2009-02-20 19:13:49 -08:00
|
|
|
{
|
2016-11-16 16:05:56 -08:00
|
|
|
r = dc->cache.rects->rects + i;
|
2009-02-20 19:13:49 -08:00
|
|
|
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
|
2013-01-11 11:57:09 -08:00
|
|
|
ret |= cb(dst, dc, x, y, glyphs,
|
|
|
|
func, r->x, r->y, r->w, r->h,
|
|
|
|
im_w, im_h);
|
2009-02-20 19:13:49 -08:00
|
|
|
}
|
2016-11-16 16:05:56 -08:00
|
|
|
evas_common_draw_context_cache_update(dc);
|
2009-02-20 19:13:49 -08:00
|
|
|
}
|
2009-02-22 23:20:21 -08:00
|
|
|
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
|
2013-01-11 11:57:09 -08:00
|
|
|
|
|
|
|
return ret;
|
2009-02-20 19:13:49 -08:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2012-07-04 02:39:23 -07:00
|
|
|
|
2012-11-29 12:47:12 -08:00
|
|
|
EAPI void
|
2012-12-17 13:27:07 -08:00
|
|
|
evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, Evas_Glyph_Array *glyphs)
|
2012-11-29 12:47:12 -08:00
|
|
|
{
|
2012-12-17 13:27:07 -08:00
|
|
|
evas_common_font_draw_cb(dst, dc, x, y, glyphs,
|
2013-01-10 17:52:46 -08:00
|
|
|
evas_common_font_rgba_draw);
|
2012-11-29 12:47:12 -08:00
|
|
|
}
|
|
|
|
|
2012-07-04 02:39:23 -07:00
|
|
|
EAPI void
|
|
|
|
evas_common_font_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Gfx_Func func,
|
|
|
|
RGBA_Image *dst, RGBA_Draw_Context *dc,
|
|
|
|
int x, int y, const Evas_Text_Props *text_props)
|
|
|
|
{
|
|
|
|
Eina_Rectangle area;
|
|
|
|
Cutout_Rect *r;
|
|
|
|
int i;
|
|
|
|
int im_w, im_h;
|
|
|
|
|
|
|
|
im_w = dst->cache_entry.w;
|
|
|
|
im_h = dst->cache_entry.h;
|
|
|
|
|
|
|
|
if (!reuse)
|
|
|
|
{
|
2012-07-04 20:11:47 -07:00
|
|
|
evas_common_draw_context_clip_clip(dc,
|
|
|
|
clip->x, clip->y,
|
|
|
|
clip->w, clip->h);
|
2013-01-10 17:52:46 -08:00
|
|
|
evas_common_font_rgba_draw(dst, dc, x, y, text_props->glyphs,
|
|
|
|
func,
|
|
|
|
dc->clip.x, dc->clip.y,
|
|
|
|
dc->clip.w, dc->clip.h,
|
|
|
|
im_w, im_h);
|
2013-06-20 04:28:18 -07:00
|
|
|
return;
|
2012-07-04 02:39:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < reuse->active; ++i)
|
|
|
|
{
|
|
|
|
r = reuse->rects + i;
|
|
|
|
|
2012-07-04 20:11:47 -07:00
|
|
|
EINA_RECTANGLE_SET(&area, r->x, r->y, r->w - 1, r->h - 1);
|
2012-07-04 02:39:23 -07:00
|
|
|
if (!eina_rectangle_intersection(&area, clip)) continue ;
|
|
|
|
evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
|
2013-01-10 17:52:46 -08:00
|
|
|
evas_common_font_rgba_draw(dst, dc, x, y, text_props->glyphs,
|
|
|
|
func, area.x, area.y, area.w, area.h,
|
|
|
|
im_w, im_h);
|
2012-07-04 02:39:23 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
2014-08-24 21:18:51 -07:00
|
|
|
evas_common_font_draw_prepare_cutout(Cutout_Rects **reuse, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Gfx_Func *func)
|
2012-07-04 02:39:23 -07:00
|
|
|
{
|
|
|
|
int im_w, im_h;
|
|
|
|
|
|
|
|
im_w = dst->cache_entry.w;
|
|
|
|
im_h = dst->cache_entry.h;
|
|
|
|
|
2014-11-12 18:27:50 -08:00
|
|
|
*func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst->cache_entry.flags.alpha, 1, dc->render_op);
|
2012-07-04 02:39:23 -07:00
|
|
|
|
2012-07-04 20:11:47 -07:00
|
|
|
evas_common_draw_context_clip_clip(dc, 0, 0, im_w, im_h);
|
|
|
|
if (dc->clip.w <= 0) return EINA_FALSE;
|
|
|
|
if (dc->clip.h <= 0) return EINA_FALSE;
|
2012-07-04 02:39:23 -07:00
|
|
|
|
|
|
|
if (dc->cutout.rects)
|
|
|
|
{
|
2014-08-24 21:18:51 -07:00
|
|
|
*reuse = evas_common_draw_context_apply_cutouts(dc, *reuse);
|
2012-07-04 02:39:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
// this draws a compressed font glyph and decompresses on the fly as it
|
|
|
|
// draws, saving memory bandwidth and providing speedups
|
|
|
|
EAPI void
|
|
|
|
evas_common_font_glyph_draw(RGBA_Font_Glyph *fg,
|
|
|
|
RGBA_Draw_Context *dc,
|
|
|
|
RGBA_Image *dst_image, int dst_pitch,
|
|
|
|
int dx, int dy, int dw, int dh, int cx, int cy, int cw, int ch)
|
|
|
|
{
|
|
|
|
RGBA_Font_Glyph_Out *fgo = fg->glyph_out;
|
|
|
|
int x, y, w, h, x1, x2, y1, y2, i, *iptr;
|
|
|
|
DATA32 *dst = dst_image->image.data;
|
|
|
|
DATA32 coltab[16], col;
|
|
|
|
DATA16 mtab[16], v;
|
|
|
|
|
2020-09-24 02:12:06 -07:00
|
|
|
if (!dst) return;
|
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
// FIXME: Use dw, dh for scaling glyphs...
|
|
|
|
(void) dw;
|
|
|
|
(void) dh;
|
|
|
|
x = dx;
|
|
|
|
y = dy;
|
|
|
|
w = fgo->bitmap.width; h = fgo->bitmap.rows;
|
|
|
|
// skip if totally clipped out
|
|
|
|
if ((y >= (cy + ch)) || ((y + h) <= cy) ||
|
|
|
|
(x >= (cx + cw)) || ((x + w) <= cx)) return;
|
|
|
|
// figure y1/y2 limit range
|
|
|
|
y1 = 0; y2 = h;
|
|
|
|
if ((y + y1) < cy) y1 = cy - y;
|
|
|
|
if ((y + y2) > (cy + ch)) y2 = cy + ch - y;
|
|
|
|
// figure x1/x2 limit range
|
|
|
|
x1 = 0; x2 = w;
|
|
|
|
if ((x + x1) < cx) x1 = cx - x;
|
|
|
|
if ((x + x2) > (cx + cw)) x2 = cx + cw - x;
|
|
|
|
col = dc->col.col;
|
|
|
|
if (dst_image->cache_entry.space == EVAS_COLORSPACE_GRY8)
|
|
|
|
{
|
|
|
|
// FIXME: Font draw not optimized for Alpha targets! SLOW!
|
|
|
|
// This is not pretty :)
|
|
|
|
|
|
|
|
DATA8 *src8, *dst8;
|
|
|
|
Draw_Func_Alpha func;
|
|
|
|
int row;
|
|
|
|
|
|
|
|
if (EINA_UNLIKELY(x < 0))
|
|
|
|
{
|
|
|
|
x1 += (-x);
|
|
|
|
x = 0;
|
|
|
|
if ((x2 - x1) <= 0) return;
|
|
|
|
}
|
|
|
|
if (EINA_UNLIKELY(y < 0))
|
|
|
|
{
|
|
|
|
y1 += (-y);
|
|
|
|
y = 0;
|
|
|
|
if ((y2 - y1) <= 0) return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dst8 = dst_image->image.data8 + x + (y * dst_pitch);
|
|
|
|
func = efl_draw_alpha_func_get(dc->render_op, EINA_FALSE);
|
|
|
|
src8 = evas_common_font_glyph_uncompress(fg, NULL, NULL);
|
|
|
|
if (!src8) return;
|
|
|
|
|
|
|
|
for (row = y1; row < y2; row++)
|
|
|
|
{
|
|
|
|
DATA8 *d = dst8 + ((row - y1) * dst_pitch);
|
|
|
|
DATA8 *s = src8 + (row * w) + x1;
|
|
|
|
func(d, s, x2 - x1);
|
|
|
|
}
|
|
|
|
free(src8);
|
|
|
|
}
|
|
|
|
else if (dc->clip.mask)
|
|
|
|
{
|
|
|
|
RGBA_Gfx_Func func;
|
|
|
|
DATA8 *src8, *mask;
|
|
|
|
DATA32 *buf, *ptr, *buf_ptr;
|
|
|
|
RGBA_Image *im = dc->clip.mask;
|
|
|
|
int row;
|
|
|
|
|
|
|
|
buf = alloca(sizeof(DATA32) * w * h);
|
|
|
|
|
|
|
|
// Adjust clipping info
|
|
|
|
if (EINA_UNLIKELY((x + x1) < dc->clip.mask_x))
|
|
|
|
x1 = dc->clip.mask_x - x;
|
|
|
|
if (EINA_UNLIKELY((y + y1) < dc->clip.mask_y))
|
|
|
|
y1 = dc->clip.mask_y - y;
|
|
|
|
if (EINA_UNLIKELY((x + x2) > (int)(x + x1 + im->cache_entry.w)))
|
|
|
|
x2 = x1 + im->cache_entry.w;
|
|
|
|
if (EINA_UNLIKELY((y + y2) > (int)(y + y1 + im->cache_entry.h)))
|
|
|
|
y2 = y1 + im->cache_entry.h;
|
|
|
|
|
|
|
|
// Step 1: alpha glyph drawing
|
|
|
|
src8 = evas_common_font_glyph_uncompress(fg, NULL, NULL);
|
|
|
|
if (!src8) return;
|
|
|
|
|
|
|
|
// Step 2: color blending to buffer
|
|
|
|
func = evas_common_gfx_func_composite_mask_color_span_get(col, dst_image->cache_entry.flags.alpha, 1, EVAS_RENDER_COPY);
|
|
|
|
for (row = y1; row < y2; row++)
|
|
|
|
{
|
|
|
|
buf_ptr = buf + (row * w) + x1;
|
|
|
|
DATA8 *s = src8 + (row * w) + x1;
|
|
|
|
func(NULL, s, col, buf_ptr, x2 - x1);
|
|
|
|
}
|
|
|
|
free(src8);
|
|
|
|
|
|
|
|
// Step 3: masking to destination
|
|
|
|
func = evas_common_gfx_func_composite_pixel_mask_span_get(im->cache_entry.flags.alpha, im->cache_entry.flags.alpha_sparse, dst_image->cache_entry.flags.alpha, dst_pitch, dc->render_op);
|
|
|
|
for (row = y1; row < y2; row++)
|
|
|
|
{
|
|
|
|
mask = im->image.data8
|
|
|
|
+ (y + row - dc->clip.mask_y) * im->cache_entry.w
|
|
|
|
+ (x + x1 - dc->clip.mask_x);
|
|
|
|
|
|
|
|
ptr = dst + (x + x1) + ((y + row) * dst_pitch);
|
|
|
|
buf_ptr = buf + (row * w) + x1;
|
2020-02-12 23:48:57 -08:00
|
|
|
func(buf_ptr, mask, 0, ptr, x2 - x1);
|
2017-11-06 18:22:09 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// build fast multiply + mask color tables to avoid compute. this works
|
|
|
|
// because of our very limited 4bit range of alpha values
|
|
|
|
for (i = 0; i <= 0xf; i++)
|
|
|
|
{
|
|
|
|
v = (i << 4) | i;
|
|
|
|
coltab[i] = MUL_SYM(v, col);
|
|
|
|
mtab[i] = 256 - (coltab[i] >> 24);
|
|
|
|
}
|
|
|
|
#ifdef BUILD_MMX
|
|
|
|
if (evas_common_cpu_has_feature(CPU_FEATURE_MMX))
|
|
|
|
{
|
|
|
|
#define MMX 1
|
|
|
|
#include "evas_font_compress_draw.c"
|
|
|
|
#undef MMX
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef BUILD_NEON
|
|
|
|
if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
|
|
|
|
{
|
|
|
|
#define NEON 1
|
|
|
|
#include "evas_font_compress_draw.c"
|
|
|
|
#undef NEON
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Plain C
|
|
|
|
{
|
|
|
|
#include "evas_font_compress_draw.c"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|