mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-09 16:57:36 +00:00
Bug 1040668 part 8 - Setup text emphasis for text run. r=jfkthame
--HG-- extra : source : 4f5398b5953c0cf4d57ed0fce5788f1430a5b05d
This commit is contained in:
parent
d80f4dcc15
commit
376cdf821b
@ -17,6 +17,7 @@
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "mozilla/BinarySearch.h"
|
||||
#include "mozilla/IntegerRange.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsBlockFrame.h"
|
||||
@ -926,6 +927,7 @@ public:
|
||||
void AssignTextRun(gfxTextRun* aTextRun, float aInflation);
|
||||
nsTextFrame* GetNextBreakBeforeFrame(uint32_t* aIndex);
|
||||
void SetupBreakSinksForTextRun(gfxTextRun* aTextRun, const void* aTextPtr);
|
||||
void SetupTextEmphasisForTextRun(gfxTextRun* aTextRun, const void* aTextPtr);
|
||||
struct FindBoundaryState {
|
||||
nsIFrame* mStopAtFrame;
|
||||
nsTextFrame* mFirstTextFrame;
|
||||
@ -1900,6 +1902,7 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
|
||||
const void* textPtr = aTextBuffer;
|
||||
bool anyTextTransformStyle = false;
|
||||
bool anyMathMLStyling = false;
|
||||
bool anyTextEmphasis = false;
|
||||
uint8_t sstyScriptLevel = 0;
|
||||
uint32_t mathFlags = 0;
|
||||
uint32_t textFlags = nsTextFrameUtils::TEXT_NO_BREAKS;
|
||||
@ -1968,6 +1971,9 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
|
||||
if (NS_STYLE_TEXT_TRANSFORM_NONE != textStyle->mTextTransform) {
|
||||
anyTextTransformStyle = true;
|
||||
}
|
||||
if (textStyle->HasTextEmphasis()) {
|
||||
anyTextEmphasis = true;
|
||||
}
|
||||
textFlags |= GetSpacingFlags(f);
|
||||
nsTextFrameUtils::CompressionMode compression =
|
||||
GetCSSWhitespaceToCompressionMode(f, textStyle);
|
||||
@ -2256,6 +2262,10 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
|
||||
// making up the textrun, but I don't see a way to avoid this.
|
||||
SetupBreakSinksForTextRun(textRun, textPtr);
|
||||
|
||||
if (anyTextEmphasis) {
|
||||
SetupTextEmphasisForTextRun(textRun, textPtr);
|
||||
}
|
||||
|
||||
if (mSkipIncompleteTextRuns) {
|
||||
mSkipIncompleteTextRuns = !TextContainsLineBreakerWhiteSpace(textPtr,
|
||||
transformedLength, mDoubleByteText);
|
||||
@ -2489,6 +2499,65 @@ BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun,
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
MayCharacterHaveEmphasisMark(uint32_t aCh)
|
||||
{
|
||||
auto category = unicode::GetGeneralCategory(aCh);
|
||||
// Comparing an unsigned variable against zero is a compile error,
|
||||
// so we use static assert here to ensure we really don't need to
|
||||
// compare it with the given constant.
|
||||
static_assert(IsUnsigned<decltype(category)>::value &&
|
||||
HB_UNICODE_GENERAL_CATEGORY_CONTROL == 0,
|
||||
"if this constant is not zero, or category is signed, "
|
||||
"we need to explicitly do the comparison below");
|
||||
return !(category <= HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED ||
|
||||
(category >= HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR &&
|
||||
category <= HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR));
|
||||
}
|
||||
|
||||
static bool
|
||||
MayCharacterHaveEmphasisMark(uint8_t aCh)
|
||||
{
|
||||
// 0x00~0x1f and 0x7f~0x9f are in category Cc
|
||||
// 0x20 and 0xa0 are in category Zs
|
||||
bool result = !(aCh <= 0x20 || (aCh >= 0x7f && aCh <= 0xa0));
|
||||
MOZ_ASSERT(result == MayCharacterHaveEmphasisMark(uint32_t(aCh)),
|
||||
"result for uint8_t should match result for uint32_t");
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
BuildTextRunsScanner::SetupTextEmphasisForTextRun(gfxTextRun* aTextRun,
|
||||
const void* aTextPtr)
|
||||
{
|
||||
if (!mDoubleByteText) {
|
||||
auto text = reinterpret_cast<const uint8_t*>(aTextPtr);
|
||||
for (auto i : MakeRange(aTextRun->GetLength())) {
|
||||
if (!MayCharacterHaveEmphasisMark(text[i])) {
|
||||
aTextRun->SetNoEmphasisMark(i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
auto text = reinterpret_cast<const char16_t*>(aTextPtr);
|
||||
auto length = aTextRun->GetLength();
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
if (NS_IS_HIGH_SURROGATE(text[i]) && i + 1 < length &&
|
||||
NS_IS_LOW_SURROGATE(text[i + 1])) {
|
||||
uint32_t ch = SURROGATE_TO_UCS4(text[i], text[i + 1]);
|
||||
if (!MayCharacterHaveEmphasisMark(ch)) {
|
||||
aTextRun->SetNoEmphasisMark(i);
|
||||
aTextRun->SetNoEmphasisMark(i + 1);
|
||||
}
|
||||
++i;
|
||||
} else {
|
||||
if (!MayCharacterHaveEmphasisMark(uint32_t(text[i]))) {
|
||||
aTextRun->SetNoEmphasisMark(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the flow corresponding to aContent in aUserData
|
||||
static inline TextRunMappedFlow*
|
||||
FindFlowForContent(TextRunUserData* aUserData, nsIContent* aContent)
|
||||
|
Loading…
x
Reference in New Issue
Block a user