2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/devel-api/text-abstraction/font-client.h>
22 #include <dali/internal/imaging/common/image-operations.h>
23 #include <dali/internal/text/text-abstraction/font-client-impl.h>
27 namespace TextAbstraction
29 const PointSize26Dot6 FontClient::DEFAULT_POINT_SIZE = 768u; // 12*64
30 const float FontClient::DEFAULT_ITALIC_ANGLE = 12.f * Dali::Math::PI_OVER_180; // FreeType documentation states the software italic is done by doing a horizontal shear of 12 degrees (file ftsynth.h).
33 const bool FontClient::DEFAULT_ATLAS_LIMITATION_ENABLED = true;
34 const uint32_t FontClient::DEFAULT_TEXT_ATLAS_WIDTH = 512u;
35 const uint32_t FontClient::DEFAULT_TEXT_ATLAS_HEIGHT = 512u;
36 const Size FontClient::DEFAULT_TEXT_ATLAS_SIZE(DEFAULT_TEXT_ATLAS_WIDTH, DEFAULT_TEXT_ATLAS_HEIGHT);
39 const uint32_t FontClient::MAX_TEXT_ATLAS_WIDTH = 1024u;
40 const uint32_t FontClient::MAX_TEXT_ATLAS_HEIGHT = 1024u;
41 const Size FontClient::MAX_TEXT_ATLAS_SIZE(MAX_TEXT_ATLAS_WIDTH, MAX_TEXT_ATLAS_HEIGHT);
43 //MAX_WIDTH_FIT_IN_ATLAS: blockWidth + 2 * DOUBLE_PIXEL_PADDING + 1u <= atlasWidth
44 //MAX_HEIGHT_FIT_IN_ATLAS: blockHeight + 2 * DOUBLE_PIXEL_PADDING + 1u <= atlasHeight
45 const uint16_t FontClient::PADDING_TEXT_ATLAS_BLOCK = 5u; // 2 * DOUBLE_PIXEL_PADDING + 1u
47 //Maximum block size to fit into atlas block
48 const Size FontClient::MAX_SIZE_FIT_IN_ATLAS(MAX_TEXT_ATLAS_WIDTH - PADDING_TEXT_ATLAS_BLOCK, MAX_TEXT_ATLAS_HEIGHT - PADDING_TEXT_ATLAS_BLOCK);
50 const uint32_t FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE = 64u; //Found this value from toolkit
52 // FontClient::GlyphBufferData
54 FontClient::GlyphBufferData::GlyphBufferData()
61 compressionType{CompressionType::NO_COMPRESSION},
68 FontClient::GlyphBufferData::~GlyphBufferData()
76 FontClient::GlyphBufferData::GlyphBufferData(FontClient::GlyphBufferData&& rhs) noexcept
80 outlineOffsetX{rhs.outlineOffsetX},
81 outlineOffsetY{rhs.outlineOffsetY},
83 compressionType{rhs.compressionType},
84 isColorEmoji{rhs.isColorEmoji},
85 isColorBitmap{rhs.isColorBitmap},
86 isBufferOwned{rhs.isBufferOwned}
90 rhs.isBufferOwned = false;
93 FontClient::GlyphBufferData& FontClient::GlyphBufferData::operator=(FontClient::GlyphBufferData&& rhs) noexcept
98 outlineOffsetX = rhs.outlineOffsetX;
99 outlineOffsetY = rhs.outlineOffsetY;
101 compressionType = rhs.compressionType;
102 isColorEmoji = rhs.isColorEmoji;
103 isColorBitmap = rhs.isColorBitmap;
104 isBufferOwned = rhs.isBufferOwned;
107 rhs.buffer = nullptr;
108 rhs.isBufferOwned = false;
113 size_t FontClient::GlyphBufferData::Compress(const uint8_t* const __restrict__ inBuffer, GlyphBufferData& __restrict__ outBufferData)
115 size_t bufferSize = 0u;
116 uint8_t*& __restrict__ compressedBuffer = outBufferData.buffer;
117 switch(outBufferData.compressionType)
119 case TextAbstraction::FontClient::GlyphBufferData::CompressionType::NO_COMPRESSION:
121 bufferSize = static_cast<size_t>(outBufferData.width) * static_cast<size_t>(outBufferData.height) * static_cast<size_t>(Pixel::GetBytesPerPixel(outBufferData.format));
123 compressedBuffer = (uint8_t*)malloc(bufferSize);
124 if(DALI_UNLIKELY(compressedBuffer == nullptr))
128 outBufferData.isBufferOwned = true;
130 // Copy buffer without compress
131 memcpy(compressedBuffer, inBuffer, bufferSize);
134 case TextAbstraction::FontClient::GlyphBufferData::CompressionType::BPP_4:
136 const uint32_t widthByte = outBufferData.width * Pixel::GetBytesPerPixel(outBufferData.format);
137 const uint32_t componentCount = (widthByte >> 1);
138 const bool considerPadding = (widthByte & 1) ? true : false;
140 // For BIT_PER_PIXEL_4 type, we can know final compressed buffer size immediatly.
141 bufferSize = static_cast<size_t>(outBufferData.height) * static_cast<size_t>(componentCount + (considerPadding ? 1 : 0));
142 compressedBuffer = (uint8_t*)malloc(bufferSize);
143 if(DALI_UNLIKELY(compressedBuffer == nullptr))
147 outBufferData.isBufferOwned = true;
149 uint8_t* __restrict__ outBufferPtr = compressedBuffer;
150 const uint8_t* __restrict__ inBufferPtr = inBuffer;
152 // Compress for each line
153 for(uint32_t y = 0; y < outBufferData.height; ++y)
155 for(uint32_t x = 0; x < componentCount; ++x)
157 const uint8_t v0 = Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++));
158 const uint8_t v1 = Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++));
160 *(outBufferPtr++) = (v0 << 4) | v1;
164 *(outBufferPtr++) = Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++));
169 case TextAbstraction::FontClient::GlyphBufferData::CompressionType::RLE_4:
171 const uint32_t widthByte = outBufferData.width * Pixel::GetBytesPerPixel(outBufferData.format);
173 // Allocate temperal buffer. Note that RLE4 can be bigger than original buffer.
174 uint8_t* __restrict__ tempBuffer = (uint8_t*)malloc(outBufferData.height * (widthByte + 1));
175 if(DALI_UNLIKELY(tempBuffer == nullptr))
180 uint8_t* __restrict__ outBufferPtr = tempBuffer;
181 const uint8_t* __restrict__ inBufferPtr = inBuffer;
185 // Compress for each line
186 for(uint32_t y = 0; y < outBufferData.height; ++y)
188 uint32_t encodedByte = 0;
189 while(encodedByte < widthByte)
191 // Case 1 : Remain only 1 byte
192 if(DALI_UNLIKELY(encodedByte + 1 == widthByte))
194 const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
195 const uint8_t v0 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev0) & 0x0f; // Intented underflow
196 *(outBufferPtr++) = v0;
200 // Case 2 : Remain only 2 byte
201 else if(DALI_UNLIKELY(encodedByte + 2 == widthByte))
203 const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
204 const uint8_t v0 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev0) & 0x0f; // Intented underflow
205 const uint8_t prev1 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
206 const uint8_t v1 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev1) & 0x0f; // Intented underflow
210 *(outBufferPtr++) = 0x80 | v0;
215 *(outBufferPtr++) = 0x10 | v0;
216 *(outBufferPtr++) = v1 << 4;
220 // Case 3 : Normal case. Remain byte bigger or equal than 3.
224 // Read 2 byte as v0 and v1.
225 // - If v0 == v1, We can compress. mark the first bit as 1. and remain 3 bit mark as the "runLength - 2".
226 // runLength can be maximum 9.
227 // - If v0 != v1, We cannot compress. mark the first bit as 0. and remain 3 bit mark as the "(nonRunLength - 1) / 2"
228 // Due to the BitPerPixel is 4, nonRunLength should be odd value.
229 // nonRunLength cutted if v0 == v1.
230 // nonRunLength can be maximum 15.
232 const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
233 const uint8_t v0 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev0) & 0x0f; // Intented underflow
234 const uint8_t prev1 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
235 const uint8_t v1 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev1) & 0x0f; // Intented underflow
237 // We can compress by RLE
240 uint8_t runLength = 2;
241 while(encodedByte < widthByte && runLength < 9)
243 const uint8_t prev2 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
244 const uint8_t v2 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr)) - prev2) & 0x0f; // Intented underflow
257 // Update (runLength - 2) result.
258 *(outBufferPtr++) = ((0x8 | (runLength - 2)) << 4) | v0;
261 // We cannot compress by RLE.
264 // Read one more value.
265 const uint8_t prev2 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
266 const uint8_t v2 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev2) & 0x0f; // Intented underflow
269 uint8_t nonRunLength = 3;
270 uint8_t* nonRunLengthHeaderPtr = outBufferPtr;
271 *(outBufferPtr++) = v0;
272 *(outBufferPtr++) = (v1 << 4) | v2;
274 while(encodedByte < widthByte && nonRunLength < 15)
276 if(DALI_LIKELY(encodedByte + 1 < widthByte))
278 const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
279 const uint8_t w0 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr)) - prew0) & 0x0f; // Intented underflow
280 const uint8_t prew1 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr + 1 - widthByte));
281 const uint8_t w1 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr + 1)) - prew1) & 0x0f; // Intented underflow
284 // Stop non-compress logic.
290 *(outBufferPtr++) = (w0 << 4) | w1;
298 // Edge case. There is only one pixel remained.
299 const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
300 const uint8_t w0 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr)) - prew0) & 0x0f; // Intented underflow
303 *(outBufferPtr++) = (w0 << 4);
306 // Increase nonRunLength 2 even latest value is invalid.
312 // Update (nonRunLength-1)/2 result into header.
313 *(nonRunLengthHeaderPtr) |= (nonRunLength >> 1) << 4;
319 // Allocate and copy data
320 compressedBuffer = (uint8_t*)malloc(bufferSize);
321 if(DALI_UNLIKELY(compressedBuffer == nullptr))
326 outBufferData.isBufferOwned = true;
328 memcpy(compressedBuffer, tempBuffer, bufferSize);
342 void FontClient::GlyphBufferData::Decompress(const GlyphBufferData& __restrict__ inBufferData, uint8_t* __restrict__ outBuffer)
344 if(DALI_UNLIKELY(outBuffer == nullptr))
349 switch(inBufferData.compressionType)
351 case TextAbstraction::FontClient::GlyphBufferData::CompressionType::NO_COMPRESSION:
353 const auto bufferSize = inBufferData.width * inBufferData.height * Pixel::GetBytesPerPixel(inBufferData.format);
355 // Copy buffer without compress
356 memcpy(outBuffer, inBufferData.buffer, bufferSize);
359 case TextAbstraction::FontClient::GlyphBufferData::CompressionType::BPP_4:
361 const uint32_t widthByte = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
362 const uint32_t componentCount = (widthByte >> 1);
363 const bool considerPadding = (widthByte & 1) ? true : false;
365 uint8_t* __restrict__ outBufferPtr = outBuffer;
366 const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer;
368 // Compress for each line
369 for(uint32_t y = 0; y < inBufferData.height; ++y)
371 for(uint32_t x = 0; x < componentCount; ++x)
373 const uint8_t v = *(inBufferPtr++);
374 const uint8_t v0 = (v >> 4) & 0x0f;
375 const uint8_t v1 = v & 0x0f;
377 *(outBufferPtr++) = (v0 << 4) | v0;
378 *(outBufferPtr++) = (v1 << 4) | v1;
382 const uint8_t v = *(inBufferPtr++);
383 *(outBufferPtr++) = (v << 4) | v;
388 case TextAbstraction::FontClient::GlyphBufferData::CompressionType::RLE_4:
390 const uint32_t widthByte = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
392 uint8_t* __restrict__ outBufferPtr = outBuffer;
393 const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer;
394 // Compress for each line
395 for(uint32_t y = 0; y < inBufferData.height; ++y)
398 uint32_t decodedByte = 0;
399 while(decodedByte < widthByte)
401 const uint8_t v = *(inBufferPtr++);
406 const uint8_t runLength = ((v >> 4) & 0x07) + 2u;
407 decodedByte += runLength;
408 const uint8_t repeatValue = v & 0x0f;
409 for(uint8_t iter = 0; iter < runLength; ++iter)
411 const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
412 const uint8_t v0 = (prev0 + repeatValue) & 0x0f;
413 *(outBufferPtr++) = (v0 << 4) | v0;
416 // Not compress by RLE
419 const uint8_t nonRunLength = (((v >> 4) & 0x07) << 1u) + 1u;
420 decodedByte += nonRunLength;
422 const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
423 const uint8_t v0 = (prev0 + (v & 0x0f)) & 0x0f;
424 *(outBufferPtr++) = (v0 << 4) | v0;
426 const bool ignoreLastValue = decodedByte > widthByte ? true : false;
427 if(DALI_UNLIKELY(ignoreLastValue))
430 for(uint8_t iter = 1; iter + 2 < nonRunLength; iter += 2)
432 const uint8_t w = *(inBufferPtr++);
433 const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
434 const uint8_t w0 = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
435 const uint8_t prew1 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte + 1)) & 0x0f;
436 const uint8_t w1 = (prew1 + (w & 0x0f)) & 0x0f;
439 *(outBufferPtr++) = (w0 << 4) | w0;
440 *(outBufferPtr++) = (w1 << 4) | w1;
444 const uint8_t w = ((*(inBufferPtr++)) >> 4) & 0x0f;
445 const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
446 const uint8_t w0 = (prew0 + w) & 0x0f;
449 *(outBufferPtr++) = (w0 << 4) | w0;
454 for(uint8_t iter = 1; iter < nonRunLength; iter += 2)
456 const uint8_t w = *(inBufferPtr++);
457 const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
458 const uint8_t w0 = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
459 const uint8_t prew1 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte + 1)) & 0x0f;
460 const uint8_t w1 = (prew1 + (w & 0x0f)) & 0x0f;
463 *(outBufferPtr++) = (w0 << 4) | w0;
464 *(outBufferPtr++) = (w1 << 4) | w1;
479 void FontClient::GlyphBufferData::DecompressScanline(const GlyphBufferData& __restrict__ inBufferData, uint8_t* __restrict__ outBuffer, uint32_t& __restrict__ offset)
481 switch(inBufferData.compressionType)
483 case TextAbstraction::FontClient::GlyphBufferData::CompressionType::NO_COMPRESSION:
485 const auto bufferSize = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
487 // Copy buffer without compress
488 memcpy(outBuffer, inBufferData.buffer + offset, bufferSize);
491 offset += bufferSize;
494 case TextAbstraction::FontClient::GlyphBufferData::CompressionType::BPP_4:
496 const uint32_t widthByte = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
497 const uint32_t componentCount = (widthByte >> 1);
498 const bool considerPadding = (widthByte & 1) ? true : false;
500 uint8_t* __restrict__ outBufferPtr = outBuffer;
501 const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer + offset;
503 // Decompress scanline
504 for(uint32_t x = 0; x < componentCount; ++x)
506 const uint8_t v = *(inBufferPtr++);
507 const uint8_t v0 = (v >> 4) & 0x0f;
508 const uint8_t v1 = v & 0x0f;
510 *(outBufferPtr++) = (v0 << 4) | v0;
511 *(outBufferPtr++) = (v1 << 4) | v1;
515 const uint8_t v = *(inBufferPtr++);
516 *(outBufferPtr++) = (v << 4) | v;
520 offset += (widthByte + 1u) >> 1u;
523 case TextAbstraction::FontClient::GlyphBufferData::CompressionType::RLE_4:
525 const uint32_t widthByte = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
527 uint8_t* __restrict__ outBufferPtr = outBuffer;
528 const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer + offset;
530 // If offset is zero, fill outBuffer as 0 first.
531 if(DALI_UNLIKELY(offset == 0))
533 memset(outBufferPtr, 0, widthByte);
536 // Decompress scanline
537 uint32_t decodedByte = 0;
538 while(decodedByte < widthByte)
540 const uint8_t v = *(inBufferPtr++);
545 const uint8_t runLength = ((v >> 4) & 0x07) + 2u;
546 decodedByte += runLength;
547 const uint8_t repeatValue = (v & 0x0f);
548 for(uint8_t iter = 0; iter < runLength; ++iter)
550 const uint8_t prev0 = (*(outBufferPtr)) & 0x0f;
551 const uint8_t v0 = (prev0 + repeatValue) & 0x0f;
552 *(outBufferPtr++) = (v0 << 4) | v0;
555 // Not compress by RLE
558 const uint8_t nonRunLength = (((v >> 4) & 0x07) << 1u) + 1u;
559 decodedByte += nonRunLength;
561 const uint8_t prev0 = (*(outBufferPtr)) & 0x0f;
562 const uint8_t v0 = (prev0 + (v & 0x0f)) & 0x0f;
563 *(outBufferPtr++) = (v0 << 4) | v0;
565 const bool ignoreLastValue = decodedByte > widthByte ? true : false;
566 if(DALI_UNLIKELY(ignoreLastValue))
569 for(uint8_t iter = 1; iter + 2 < nonRunLength; iter += 2)
571 const uint8_t w = *(inBufferPtr++);
572 const uint8_t prew0 = (*(outBufferPtr)) & 0x0f;
573 const uint8_t w0 = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
574 const uint8_t prew1 = (*(outBufferPtr + 1)) & 0x0f;
575 const uint8_t w1 = (prew1 + (w & 0x0f)) & 0x0f;
578 *(outBufferPtr++) = (w0 << 4) | w0;
579 *(outBufferPtr++) = (w1 << 4) | w1;
583 const uint8_t w = ((*(inBufferPtr++)) >> 4) & 0x0f;
584 const uint8_t prew0 = (*(outBufferPtr)) & 0x0f;
585 const uint8_t w0 = (prew0 + w) & 0x0f;
588 *(outBufferPtr++) = (w0 << 4) | w0;
593 for(uint8_t iter = 1; iter < nonRunLength; iter += 2)
595 const uint8_t w = *(inBufferPtr++);
596 const uint8_t prew0 = (*(outBufferPtr)) & 0x0f;
597 const uint8_t w0 = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
598 const uint8_t prew1 = (*(outBufferPtr + 1)) & 0x0f;
599 const uint8_t w1 = (prew1 + (w & 0x0f)) & 0x0f;
602 *(outBufferPtr++) = (w0 << 4) | w0;
603 *(outBufferPtr++) = (w1 << 4) | w1;
619 FontClient FontClient::Get()
621 return Internal::FontClient::Get();
624 FontClient::FontClient()
628 FontClient::~FontClient()
632 FontClient::FontClient(const FontClient& handle) = default;
634 FontClient& FontClient::operator=(const FontClient& handle) = default;
636 FontClient::FontClient(FontClient&& handle) = default;
638 FontClient& FontClient::operator=(FontClient&& handle) = default;
640 void FontClient::ClearCache()
642 GetImplementation(*this).ClearCache();
645 void FontClient::SetDpi(unsigned int horizontalDpi, unsigned int verticalDpi)
647 GetImplementation(*this).SetDpi(horizontalDpi, verticalDpi);
650 void FontClient::GetDpi(unsigned int& horizontalDpi, unsigned int& verticalDpi)
652 GetImplementation(*this).GetDpi(horizontalDpi, verticalDpi);
655 int FontClient::GetDefaultFontSize()
657 return GetImplementation(*this).GetDefaultFontSize();
660 void FontClient::ResetSystemDefaults()
662 GetImplementation(*this).ResetSystemDefaults();
665 void FontClient::GetDefaultFonts(FontList& defaultFonts)
667 GetImplementation(*this).GetDefaultFonts(defaultFonts);
670 void FontClient::GetDefaultPlatformFontDescription(FontDescription& fontDescription)
672 GetImplementation(*this).GetDefaultPlatformFontDescription(fontDescription);
675 void FontClient::GetSystemFonts(FontList& systemFonts)
677 GetImplementation(*this).GetSystemFonts(systemFonts);
680 void FontClient::GetDescription(FontId fontId, FontDescription& fontDescription)
682 GetImplementation(*this).GetDescription(fontId, fontDescription);
685 PointSize26Dot6 FontClient::GetPointSize(FontId fontId)
687 return GetImplementation(*this).GetPointSize(fontId);
690 bool FontClient::IsCharacterSupportedByFont(FontId fontId, Character character)
692 return GetImplementation(*this).IsCharacterSupportedByFont(fontId, character);
695 FontId FontClient::FindDefaultFont(Character charcode,
696 PointSize26Dot6 requestedPointSize,
699 return GetImplementation(*this).FindDefaultFont(charcode,
704 FontId FontClient::FindFallbackFont(Character charcode,
705 const FontDescription& preferredFontDescription,
706 PointSize26Dot6 requestedPointSize,
709 return GetImplementation(*this).FindFallbackFont(charcode, preferredFontDescription, requestedPointSize, preferColor);
712 FontId FontClient::GetFontId(const FontPath& path, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex)
714 return GetImplementation(*this).GetFontId(path, requestedPointSize, faceIndex);
717 FontId FontClient::GetFontId(const FontDescription& fontDescription,
718 PointSize26Dot6 requestedPointSize,
721 return GetImplementation(*this).GetFontId(fontDescription,
726 FontId FontClient::GetFontId(const BitmapFont& bitmapFont)
728 return GetImplementation(*this).GetFontId(bitmapFont);
731 bool FontClient::IsScalable(const FontPath& path)
733 return GetImplementation(*this).IsScalable(path);
736 bool FontClient::IsScalable(const FontDescription& fontDescription)
738 return GetImplementation(*this).IsScalable(fontDescription);
741 void FontClient::GetFixedSizes(const FontPath& path, Dali::Vector<PointSize26Dot6>& sizes)
743 GetImplementation(*this).GetFixedSizes(path, sizes);
746 void FontClient::GetFixedSizes(const FontDescription& fontDescription,
747 Dali::Vector<PointSize26Dot6>& sizes)
749 GetImplementation(*this).GetFixedSizes(fontDescription, sizes);
752 bool FontClient::HasItalicStyle(FontId fontId) const
754 return GetImplementation(*this).HasItalicStyle(fontId);
757 void FontClient::GetFontMetrics(FontId fontId, FontMetrics& metrics)
759 GetImplementation(*this).GetFontMetrics(fontId, metrics);
762 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode)
764 return GetImplementation(*this).GetGlyphIndex(fontId, charcode);
767 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode, Character variantSelector)
769 return GetImplementation(*this).GetGlyphIndex(fontId, charcode, variantSelector);
772 bool FontClient::GetGlyphMetrics(GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal)
774 return GetImplementation(*this).GetGlyphMetrics(array, size, type, horizontal);
777 void FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, bool isItalicRequired, bool isBoldRequired, GlyphBufferData& data, int outlineWidth)
779 GetImplementation(*this).CreateBitmap(fontId, glyphIndex, isItalicRequired, isBoldRequired, data, outlineWidth);
782 PixelData FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, int outlineWidth)
784 return GetImplementation(*this).CreateBitmap(fontId, glyphIndex, outlineWidth);
787 void FontClient::CreateVectorBlob(FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight)
789 GetImplementation(*this).CreateVectorBlob(fontId, glyphIndex, blob, blobLength, nominalWidth, nominalHeight);
792 const GlyphInfo& FontClient::GetEllipsisGlyph(PointSize26Dot6 requestedPointSize)
794 return GetImplementation(*this).GetEllipsisGlyph(requestedPointSize);
797 bool FontClient::IsColorGlyph(FontId fontId, GlyphIndex glyphIndex)
799 return GetImplementation(*this).IsColorGlyph(fontId, glyphIndex);
802 bool FontClient::AddCustomFontDirectory(const FontPath& path)
804 return GetImplementation(*this).AddCustomFontDirectory(path);
807 GlyphIndex FontClient::CreateEmbeddedItem(const EmbeddedItemDescription& description, Pixel::Format& pixelFormat)
809 return GetImplementation(*this).CreateEmbeddedItem(description, pixelFormat);
812 void FontClient::EnableAtlasLimitation(bool enabled)
814 return GetImplementation(*this).EnableAtlasLimitation(enabled);
817 bool FontClient::IsAtlasLimitationEnabled() const
819 return GetImplementation(*this).IsAtlasLimitationEnabled();
822 Size FontClient::GetMaximumTextAtlasSize() const
824 return GetImplementation(*this).GetMaximumTextAtlasSize();
827 Size FontClient::GetDefaultTextAtlasSize() const
829 return GetImplementation(*this).GetDefaultTextAtlasSize();
832 Size FontClient::GetCurrentMaximumBlockSizeFitInAtlas() const
834 return GetImplementation(*this).GetCurrentMaximumBlockSizeFitInAtlas();
837 bool FontClient::SetCurrentMaximumBlockSizeFitInAtlas(const Size& currentMaximumBlockSizeFitInAtlas)
839 return GetImplementation(*this).SetCurrentMaximumBlockSizeFitInAtlas(currentMaximumBlockSizeFitInAtlas);
842 uint32_t FontClient::GetNumberOfPointsPerOneUnitOfPointSize() const
844 return GetImplementation(*this).GetNumberOfPointsPerOneUnitOfPointSize();
847 FontClient::FontClient(Internal::FontClient* internal)
848 : BaseHandle(internal)
852 FontClient FontClientPreInitialize()
854 return Internal::FontClient::PreInitialize();
857 } // namespace TextAbstraction