void LayoutSVGInlineText::updateMetricsList(bool& lastCharacterWasWhiteSpace) { m_metrics.clear(); if (!textLength()) return; TextRun run = constructTextRun(*this, 0, textLength(), styleRef().direction()); BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; BidiRunList<BidiCharacterRun>& bidiRuns = bidiResolver.runs(); bool bidiOverride = isOverride(styleRef().unicodeBidi()); BidiStatus status(LTR, bidiOverride); if (run.is8Bit() || bidiOverride) { WTF::Unicode::CharDirection direction = WTF::Unicode::LeftToRight; // If BiDi override is in effect, use the specified direction. if (bidiOverride && !styleRef().isLeftToRightDirection()) direction = WTF::Unicode::RightToLeft; bidiRuns.addRun(new BidiCharacterRun(0, run.charactersLength(), status.context.get(), direction)); } else { status.last = status.lastStrong = WTF::Unicode::OtherNeutral; bidiResolver.setStatus(status); bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&run, 0)); const bool hardLineBreak = false; const bool reorderRuns = false; bidiResolver.createBidiRunsForLine(TextRunIterator(&run, run.length()), NoVisualOverride, hardLineBreak, reorderRuns); } for (const BidiCharacterRun* bidiRun = bidiRuns.firstRun(); bidiRun; bidiRun = bidiRun->next()) { TextRun subRun = constructTextRun(*this, bidiRun->start(), bidiRun->stop() - bidiRun->start(), bidiRun->direction()); addMetricsFromRun(subRun, lastCharacterWasWhiteSpace); } bidiResolver.runs().deleteRuns(); }
TextRun SVGTextMetrics::constructTextRun(LineLayoutSVGInlineText textLayoutItem, unsigned position, unsigned length, TextDirection textDirection) { const ComputedStyle& style = textLayoutItem.styleRef(); TextRun run(static_cast<const LChar*>(nullptr) // characters, will be set below if non-zero. , 0 // length, will be set below if non-zero. , 0 // xPos, only relevant with allowTabs=true , 0 // padding, only relevant for justified text, not relevant for SVG , TextRun::AllowTrailingExpansion , textDirection , isOverride(style.unicodeBidi()) /* directionalOverride */); if (length) { if (textLayoutItem.is8Bit()) run.setText(textLayoutItem.characters8() + position, length); else run.setText(textLayoutItem.characters16() + position, length); } // We handle letter & word spacing ourselves. run.disableSpacing(); // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring. run.setCharactersLength(textLayoutItem.textLength() - position); ASSERT(run.charactersLength() >= run.length()); return run; }
void PopupMenuImpl::addElementStyle(HTMLElement& element, bool enableExtraStyling, SharedBuffer* data) { const ComputedStyle* style = m_client->computedStyleForItem(element); ASSERT(style); PagePopupClient::addString("style: {\n", data); addProperty("visibility", String(style->visibility() == HIDDEN ? "hidden" : ""), data); addProperty("display", String(style->display() == NONE ? "none" : ""), data); addProperty("direction", String(style->direction() == RTL ? "rtl" : "ltr"), data); addProperty("unicodeBidi", String(isOverride(style->unicodeBidi()) ? "bidi-override" : "normal"), data); if (enableExtraStyling) { addProperty("color", style->visitedDependentColor(CSSPropertyColor).serialized(), data); addProperty("backgroundColor", style->visitedDependentColor(CSSPropertyBackgroundColor).serialized(), data); const FontDescription& fontDescription = style->font().fontDescription(); addProperty("fontSize", fontDescription.computedPixelSize(), data); addProperty("fontWeight", String(fontWeightToString(fontDescription.weight())), data); PagePopupClient::addString("fontFamily: [\n", data); for (const FontFamily* f = &fontDescription.family(); f; f = f->next()) { addJavaScriptString(f->family().string(), data); if (f->next()) PagePopupClient::addString(",\n", data); } PagePopupClient::addString("],\n", data); addProperty("fontStyle", String(fontStyleToString(fontDescription.style())), data); addProperty("fontVariant", String(fontVariantToString(fontDescription.variant())), data); addProperty("textTransform", String(textTransformToString(style->textTransform())), data); } PagePopupClient::addString("},\n", data); }
TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText* text, unsigned position, unsigned length, TextDirection textDirection) { RenderStyle* style = text->style(); ASSERT(style); TextRun run(static_cast<const LChar*>(0) // characters, will be set below if non-zero. , 0 // length, will be set below if non-zero. , 0 // xPos, only relevant with allowTabs=true , 0 // padding, only relevant for justified text, not relevant for SVG , TextRun::AllowTrailingExpansion , textDirection , isOverride(style->unicodeBidi()) /* directionalOverride */); if (length) { if (text->is8Bit()) run.setText(text->characters8() + position, length); else run.setText(text->characters16() + position, length); } if (textRunNeedsRenderingContext(style->font())) run.setRenderingContext(SVGTextRunRenderingContext::create(text)); // We handle letter & word spacing ourselves. run.disableSpacing(); // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring. run.setCharactersLength(text->textLength() - position); ASSERT(run.charactersLength() >= run.length()); return run; }
TextDirection determinePlaintextDirectionality(LayoutObject* root, LayoutObject* current, unsigned pos) { LayoutObject* firstLayoutObject = firstLayoutObjectForDirectionalityDetermination(root, current); InlineIterator iter(LineLayoutItem(root), LineLayoutItem(firstLayoutObject), firstLayoutObject == current ? pos : 0); InlineBidiResolver observer; observer.setStatus(BidiStatus(root->style()->direction(), isOverride(root->style()->unicodeBidi()))); observer.setPositionIgnoringNestedIsolates(iter); return observer.determineParagraphDirectionality(); }
void UnnecessaryValueParamCheck::registerMatchers(MatchFinder *Finder) { const auto ExpensiveValueParamDecl = parmVarDecl(hasType(hasCanonicalType(allOf(matchers::isExpensiveToCopy(), unless(referenceType())))), decl().bind("param")); Finder->addMatcher( functionDecl(isDefinition(), unless(cxxMethodDecl(isOverride())), unless(isInstantiated()), has(typeLoc(forEach(ExpensiveValueParamDecl))), decl().bind("functionDecl")), this); }
void VirtualNearMissCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus) return; Finder->addMatcher( cxxMethodDecl( unless(anyOf(isOverride(), isImplicit(), cxxConstructorDecl(), cxxDestructorDecl(), cxxConversionDecl(), isStatic(), isOverloadedOperator()))) .bind("method"), this); }
TextDirection determinePlaintextDirectionality(RenderObject* root, RenderObject* current, unsigned pos) { InlineIterator iter( root, firstRenderObjectForDirectionalityDetermination(root, current), pos); InlineBidiResolver observer; observer.setStatus(BidiStatus(root->style()->direction(), isOverride(root->style()->unicodeBidi()))); observer.setPositionIgnoringNestedIsolates(iter); return observer.determineParagraphDirectionality(); }
void PopupMenuImpl::addElementStyle(ItemIterationContext& context, HTMLElement& element) { const ComputedStyle* style = m_ownerElement->itemComputedStyle(element); ASSERT(style); SharedBuffer* data = context.m_buffer; // TODO(tkent): We generate unnecessary "style: {\n},\n" even if no // additional style. PagePopupClient::addString("style: {\n", data); if (style->visibility() == HIDDEN) addProperty("visibility", String("hidden"), data); if (style->display() == NONE) addProperty("display", String("none"), data); const ComputedStyle& baseStyle = context.baseStyle(); if (baseStyle.direction() != style->direction()) addProperty("direction", String(style->direction() == RTL ? "rtl" : "ltr"), data); if (isOverride(style->unicodeBidi())) addProperty("unicodeBidi", String("bidi-override"), data); Color foregroundColor = style->visitedDependentColor(CSSPropertyColor); if (baseStyle.visitedDependentColor(CSSPropertyColor) != foregroundColor) addProperty("color", foregroundColor.serialized(), data); Color backgroundColor = style->visitedDependentColor(CSSPropertyBackgroundColor); if (context.backgroundColor() != backgroundColor && backgroundColor != Color::transparent) addProperty("backgroundColor", backgroundColor.serialized(), data); const FontDescription& baseFont = context.baseFont(); const FontDescription& fontDescription = style->font().fontDescription(); if (baseFont.computedPixelSize() != fontDescription.computedPixelSize()) { // We don't use FontDescription::specifiedSize() because this element // might have its own zoom level. addProperty("fontSize", fontDescription.computedSize() / zoomFactor(), data); } // Our UA stylesheet has font-weight:normal for OPTION. if (FontWeightNormal != fontDescription.weight()) addProperty("fontWeight", String(fontWeightToString(fontDescription.weight())), data); if (baseFont.family() != fontDescription.family()) { PagePopupClient::addString("fontFamily: [\n", data); for (const FontFamily* f = &fontDescription.family(); f; f = f->next()) { addJavaScriptString(f->family().string(), data); if (f->next()) PagePopupClient::addString(",\n", data); } PagePopupClient::addString("],\n", data); } if (baseFont.style() != fontDescription.style()) addProperty("fontStyle", String(fontStyleToString(fontDescription.style())), data); if (baseFont.variant() != fontDescription.variant()) addProperty("fontVariant", String(fontVariantToString(fontDescription.variant())), data); if (baseStyle.textTransform() != style->textTransform()) addProperty("textTransform", String(textTransformToString(style->textTransform())), data); PagePopupClient::addString("},\n", data); }
static inline TextRun constructTextRunInternal(RenderObject* context, const Font& font, const CharacterType* characters, int length, RenderStyle* style, TextDirection direction, TextRun::ExpansionBehavior expansion, TextRunFlags flags) { ASSERT(style); TextDirection textDirection = direction; bool directionalOverride = style->rtlOrdering() == VisualOrder; if (flags != DefaultTextRunFlags) { if (flags & RespectDirection) textDirection = style->direction(); if (flags & RespectDirectionOverride) directionalOverride |= isOverride(style->unicodeBidi()); } return TextRun(characters, length, 0, 0, expansion, textDirection, directionalOverride); }
void SoPolygonOffset::doAction(SoAction * action) { SoState *state= action->getState(); if(SoOverrideElement::getPolygonOffsetOverride(state)) return; SoPolygonOffsetElement::set(state, this, factor.getValue(), units.getValue(), (SoPolygonOffsetElement::Style)styles.getValue(), on.getValue()); if(isOverride()) SoOverrideElement::setPolygonOffsetOverride(state, this, TRUE); }
void SVGTextMetricsCalculator::setupBidiRuns() { RenderStyle* style = m_text->style(); m_textDirection = style->direction(); if (isOverride(style->unicodeBidi())) return; BidiStatus status(LTR, false); status.last = status.lastStrong = WTF::Unicode::OtherNeutral; m_bidiResolver.setStatus(status); m_bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&m_run, 0)); const bool hardLineBreak = false; const bool reorderRuns = false; m_bidiResolver.createBidiRunsForLine(TextRunIterator(&m_run, m_run.length()), NoVisualOverride, hardLineBreak, reorderRuns); BidiRunList<BidiCharacterRun>& bidiRuns = m_bidiResolver.runs(); m_bidiRun = bidiRuns.firstRun(); }
static inline TextRun constructTextRunInternal(const Font& font, const CharacterType* characters, int length, const ComputedStyle& style, TextDirection direction, TextRunFlags flags) { TextDirection textDirection = direction; bool directionalOverride = style.rtlOrdering() == EOrder::Visual; if (flags != DefaultTextRunFlags) { if (flags & RespectDirection) textDirection = style.direction(); if (flags & RespectDirectionOverride) directionalOverride |= isOverride(style.unicodeBidi()); } TextRun::ExpansionBehavior expansion = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion; TextRun run(characters, length, 0, 0, expansion, textDirection, directionalOverride); return run; }
void ExternalPopupMenu::getPopupMenuInfo(WebPopupMenuInfo& info, HTMLSelectElement& ownerElement) { const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = ownerElement.listItems(); size_t itemCount = listItems.size(); size_t count = 0; Vector<WebMenuItemInfo> items(itemCount); for (size_t i = 0; i < itemCount; ++i) { if (ownerElement.itemIsDisplayNone(*listItems[i])) continue; Element& itemElement = *listItems[i]; WebMenuItemInfo& popupItem = items[count++]; popupItem.label = ownerElement.itemText(itemElement); popupItem.toolTip = itemElement.title(); popupItem.checked = false; if (isHTMLHRElement(itemElement)) { popupItem.type = WebMenuItemInfo::Separator; } else if (isHTMLOptGroupElement(itemElement)) { popupItem.type = WebMenuItemInfo::Group; } else { popupItem.type = WebMenuItemInfo::Option; popupItem.checked = toHTMLOptionElement(itemElement).selected(); } popupItem.enabled = !itemElement.isDisabledFormControl(); const ComputedStyle& style = *ownerElement.itemComputedStyle(itemElement); popupItem.textDirection = toWebTextDirection(style.direction()); popupItem.hasTextDirectionOverride = isOverride(style.unicodeBidi()); } const ComputedStyle& menuStyle = ownerElement.computedStyle() ? *ownerElement.computedStyle() : *ownerElement.ensureComputedStyle(); info.itemHeight = menuStyle.font().fontMetrics().height(); info.itemFontSize = static_cast<int>(menuStyle.font().fontDescription().computedSize()); info.selectedIndex = toExternalPopupMenuItemIndex(ownerElement.optionToListIndex(ownerElement.selectedIndex()), ownerElement); info.rightAligned = menuStyle.direction() == RTL; info.allowMultipleSelection = ownerElement.multiple(); if (count < itemCount) items.shrink(count); info.items = items; }
void SoTexture2::doAction(SoAction *action) // //////////////////////////////////////////////////////////////////////// { SoState * state = action->getState(); if (image.isIgnored() || SoTextureOverrideElement::getImageOverride(state)) return; // Texture being overriden or this node ignored if (isOverride()) { SoTextureOverrideElement::setImageOverride(state, TRUE); } SbVec2s size; int nc; const unsigned char *bytes = image.getValue(size, nc); int numBytes = size[0]*size[1]*nc; SoTextureImageElement::set(state, this, size, nc, bytes, wrapS.getValue(), wrapT.getValue(), model.getValue(), blendColor.getValue()); }
void UseOverride::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(methodDecl(isOverride()).bind("method"), this); }
void VarDeclaration::semantic(Scope *sc) { #if 0 printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); printf(" type = %s\n", type ? type->toChars() : "null"); printf(" stc = x%x\n", sc->stc); printf(" storage_class = x%x\n", storage_class); printf("linkage = %d\n", sc->linkage); //if (strcmp(toChars(), "mul") == 0) halt(); #endif storage_class |= sc->stc; if (storage_class & STCextern && init) error("extern symbols cannot have initializers"); AggregateDeclaration *ad = isThis(); if (ad) storage_class |= ad->storage_class & STC_TYPECTOR; /* If auto type inference, do the inference */ int inferred = 0; if (!type) { inuse++; type = init->inferType(sc); inuse--; inferred = 1; /* This is a kludge to support the existing syntax for RAII * declarations. */ storage_class &= ~STCauto; originalType = type; } else { if (!originalType) originalType = type; type = type->semantic(loc, sc); } //printf(" semantic type = %s\n", type ? type->toChars() : "null"); type->checkDeprecated(loc, sc); linkage = sc->linkage; this->parent = sc->parent; //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); protection = sc->protection; //printf("sc->stc = %x\n", sc->stc); //printf("storage_class = x%x\n", storage_class); #if DMDV2 if (storage_class & STCgshared && global.params.safe && !sc->module->safe) { error("__gshared not allowed in safe mode; use shared"); } #endif Dsymbol *parent = toParent(); FuncDeclaration *fd = parent->isFuncDeclaration(); Type *tb = type->toBasetype(); if (tb->ty == Tvoid && !(storage_class & STClazy)) { error("voids have no value"); type = Type::terror; tb = type; } if (tb->ty == Tfunction) { error("cannot be declared to be a function"); type = Type::terror; tb = type; } if (tb->ty == Tstruct) { TypeStruct *ts = (TypeStruct *)tb; if (!ts->sym->members) { error("no definition of struct %s", ts->toChars()); } } if ((storage_class & STCauto) && !inferred) error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?"); if (tb->ty == Ttuple) { /* Instead, declare variables for each of the tuple elements * and add those. */ TypeTuple *tt = (TypeTuple *)tb; size_t nelems = Parameter::dim(tt->arguments); Objects *exps = new Objects(); exps->setDim(nelems); Expression *ie = init ? init->toExpression() : NULL; for (size_t i = 0; i < nelems; i++) { Parameter *arg = Parameter::getNth(tt->arguments, i); OutBuffer buf; buf.printf("_%s_field_%zu", ident->toChars(), i); buf.writeByte(0); const char *name = (const char *)buf.extractData(); Identifier *id = Lexer::idPool(name); Expression *einit = ie; if (ie && ie->op == TOKtuple) { einit = (Expression *)((TupleExp *)ie)->exps->data[i]; } Initializer *ti = init; if (einit) { ti = new ExpInitializer(einit->loc, einit); } VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); v->semantic(sc); #if !IN_LLVM // removed for LDC since TupleDeclaration::toObj already creates the fields; // adding them to the scope again leads to duplicates if (sc->scopesym) { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars()); if (sc->scopesym->members) sc->scopesym->members->push(v); } #endif Expression *e = new DsymbolExp(loc, v); exps->data[i] = e; } TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps); v2->isexp = 1; aliassym = v2; return; } if (storage_class & STCconst && !init && !fd) // Initialize by constructor only storage_class = (storage_class & ~STCconst) | STCctorinit; if (isConst()) { } else if (isStatic()) { } else if (isSynchronized()) { error("variable %s cannot be synchronized", toChars()); } else if (isOverride()) { error("override cannot be applied to variable"); } else if (isAbstract()) { error("abstract cannot be applied to variable"); } else if (storage_class & STCtemplateparameter) { } else if (storage_class & STCctfe) { } else { AggregateDeclaration *aad = sc->anonAgg; if (!aad) aad = parent->isAggregateDeclaration(); if (aad) { #if DMDV2 assert(!(storage_class & (STCextern | STCstatic | STCtls | STCgshared))); if (storage_class & (STCconst | STCimmutable) && init) { if (!type->toBasetype()->isTypeBasic()) storage_class |= STCstatic; } else #endif aad->addField(sc, this); } InterfaceDeclaration *id = parent->isInterfaceDeclaration(); if (id) { error("field not allowed in interface"); } /* Templates cannot add fields to aggregates */ TemplateInstance *ti = parent->isTemplateInstance(); if (ti) { // Take care of nested templates while (1) { TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance(); if (!ti2) break; ti = ti2; } // If it's a member template AggregateDeclaration *ad = ti->tempdecl->isMember(); if (ad && storage_class != STCundefined) { error("cannot use template to add field to aggregate '%s'", ad->toChars()); } } } #if DMDV2 if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && ident != Id::This) { error("only parameters or foreach declarations can be ref"); } #endif if (type->isscope() && !noscope) { if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) { error("globals, statics, fields, ref and out parameters cannot be auto"); } if (!(storage_class & STCscope)) { if (!(storage_class & STCparameter) && ident != Id::withSym) error("reference to scope class must be scope"); } } enum TOK op = TOKconstruct; if (!init && !sc->inunion && !isStatic() && !isConst() && fd && !(storage_class & (STCfield | STCin | STCforeach)) && type->size() != 0) { // Provide a default initializer //printf("Providing default initializer for '%s'\n", toChars()); if (type->ty == Tstruct && ((TypeStruct *)type)->sym->zeroInit == 1) { /* If a struct is all zeros, as a special case * set it's initializer to the integer 0. * In AssignExp::toElem(), we check for this and issue * a memset() to initialize the struct. * Must do same check in interpreter. */ Expression *e = new IntegerExp(loc, 0, Type::tint32); Expression *e1; e1 = new VarExp(loc, this); e = new AssignExp(loc, e1, e); e->op = TOKconstruct; e->type = e1->type; // don't type check this, it would fail init = new ExpInitializer(loc, e); return; } else if (type->ty == Ttypedef) { TypeTypedef *td = (TypeTypedef *)type; if (td->sym->init) { init = td->sym->init; ExpInitializer *ie = init->isExpInitializer(); if (ie) // Make copy so we can modify it init = new ExpInitializer(ie->loc, ie->exp); } else init = getExpInitializer(); } else { init = getExpInitializer(); } // Default initializer is always a blit op = TOKblit; } if (init) { sc = sc->push(); sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCref); ArrayInitializer *ai = init->isArrayInitializer(); if (ai && tb->ty == Taarray) { init = ai->toAssocArrayInitializer(); } StructInitializer *si = init->isStructInitializer(); ExpInitializer *ei = init->isExpInitializer(); // See if initializer is a NewExp that can be allocated on the stack if (ei && isScope() && ei->exp->op == TOKnew) { NewExp *ne = (NewExp *)ei->exp; if (!(ne->newargs && ne->newargs->dim)) { ne->onstack = 1; onstack = 1; if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL)) onstack = 2; } } // If inside function, there is no semantic3() call if (sc->func) { // If local variable, use AssignExp to handle all the various // possibilities. if (fd && !isStatic() && !isConst() && !init->isVoidInitializer()) { //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); if (!ei) { Expression *e = init->toExpression(); if (!e) { init = init->semantic(sc, type); e = init->toExpression(); if (!e) { error("is not a static and cannot have static initializer"); return; } } ei = new ExpInitializer(init->loc, e); init = ei; } Expression *e1 = new VarExp(loc, this); Type *t = type->toBasetype(); if (t->ty == Tsarray && !(storage_class & (STCref | STCout))) { ei->exp = ei->exp->semantic(sc); if (!ei->exp->implicitConvTo(type)) { int dim = ((TypeSArray *)t)->dim->toInteger(); // If multidimensional static array, treat as one large array while (1) { t = t->nextOf()->toBasetype(); if (t->ty != Tsarray) break; dim *= ((TypeSArray *)t)->dim->toInteger(); e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex)); } } e1 = new SliceExp(loc, e1, NULL, NULL); } else if (t->ty == Tstruct) { ei->exp = ei->exp->semantic(sc); ei->exp = resolveProperties(sc, ei->exp); StructDeclaration *sd = ((TypeStruct *)t)->sym; #if DMDV2 /* Look to see if initializer is a call to the constructor */ if (sd->ctor && // there are constructors ei->exp->type->ty == Tstruct && // rvalue is the same struct ((TypeStruct *)ei->exp->type)->sym == sd && ei->exp->op == TOKstar) { /* Look for form of constructor call which is: * *__ctmp.ctor(arguments...) */ PtrExp *pe = (PtrExp *)ei->exp; if (pe->e1->op == TOKcall) { CallExp *ce = (CallExp *)pe->e1; if (ce->e1->op == TOKdotvar) { DotVarExp *dve = (DotVarExp *)ce->e1; if (dve->var->isCtorDeclaration()) { /* It's a constructor call, currently constructing * a temporary __ctmp. */ /* Before calling the constructor, initialize * variable with a bit copy of the default * initializer */ Expression *e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc)); e->op = TOKblit; e->type = t; ei->exp = new CommaExp(loc, e, ei->exp); /* Replace __ctmp being constructed with e1 */ dve->e1 = e1; return; } } } } #endif if (!ei->exp->implicitConvTo(type)) { /* Look for opCall * See bugzilla 2702 for more discussion */ Type *ti = ei->exp->type->toBasetype(); // Don't cast away invariant or mutability in initializer if (search_function(sd, Id::call) && /* Initializing with the same type is done differently */ !(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc))) { // Rewrite as e1.call(arguments) Expression * eCall = new DotIdExp(loc, e1, Id::call); ei->exp = new CallExp(loc, eCall, ei->exp); } } } ei->exp = new AssignExp(loc, e1, ei->exp); ei->exp->op = TOKconstruct; canassign++; ei->exp = ei->exp->semantic(sc); canassign--; ei->exp->optimize(WANTvalue); } else { init = init->semantic(sc, type); if (fd && isConst() && !isStatic()) { // Make it static storage_class |= STCstatic; } } } else if (isConst() || isFinal() || parent->isAggregateDeclaration()) { /* Because we may need the results of a const declaration in a * subsequent type, such as an array dimension, before semantic2() * gets ordinarily run, try to run semantic2() now. * Ignore failure. */ if (!global.errors && !inferred) { unsigned errors = global.errors; global.gag++; //printf("+gag\n"); Expression *e; Initializer *i2 = init; inuse++; if (ei) { e = ei->exp->syntaxCopy(); e = e->semantic(sc); e = e->implicitCastTo(sc, type); } else if (si || ai) { i2 = init->syntaxCopy(); i2 = i2->semantic(sc, type); } inuse--; global.gag--; //printf("-gag\n"); if (errors != global.errors) // if errors happened { if (global.gag == 0) global.errors = errors; // act as if nothing happened #if DMDV2 /* Save scope for later use, to try again */ scope = new Scope(*sc); scope->setNoFree(); #endif } else if (ei) { if (isDataseg() || (storage_class & STCmanifest)) e = e->optimize(WANTvalue | WANTinterpret); else e = e->optimize(WANTvalue); switch (e->op) { case TOKint64: case TOKfloat64: case TOKstring: case TOKarrayliteral: case TOKassocarrayliteral: case TOKstructliteral: case TOKnull: ei->exp = e; // no errors, keep result break; default: #if DMDV2 /* Save scope for later use, to try again */ scope = new Scope(*sc); scope->setNoFree(); #endif break; } } else init = i2; // no errors, keep result } } sc = sc->pop(); } }
void UseOverrideCheck::registerMatchers(MatchFinder *Finder) { // Only register the matcher for C++11. if (getLangOpts().CPlusPlus11) Finder->addMatcher(cxxMethodDecl(isOverride()).bind("method"), this); }
void CanvasRenderingContext2D::drawTextInternal( const String& text, double x, double y, CanvasRenderingContext2DState::PaintType paintType, double* maxWidth) { // The style resolution required for fonts is not available in frame-less // documents. if (!canvas()->document().frame()) return; // accessFont needs the style to be up to date, but updating style can cause // script to run, (e.g. due to autofocus) which can free the canvas (set size // to 0, for example), so update style before grabbing the drawingCanvas. canvas()->document().updateStyleAndLayoutTreeForNode(canvas()); SkCanvas* c = drawingCanvas(); if (!c) return; if (!std::isfinite(x) || !std::isfinite(y)) return; if (maxWidth && (!std::isfinite(*maxWidth) || *maxWidth <= 0)) return; // Currently, SkPictureImageFilter does not support subpixel text // anti-aliasing, which is expected when !creationAttributes().alpha(), so we // need to fall out of display list mode when drawing text to an opaque // canvas. crbug.com/583809 if (!creationAttributes().alpha() && !isAccelerated()) canvas()->disableDeferral( DisableDeferralReasonSubPixelTextAntiAliasingSupport); const Font& font = accessFont(); font.getFontDescription().setSubpixelAscentDescent(true); const SimpleFontData* fontData = font.primaryFont(); DCHECK(fontData); if (!fontData) return; const FontMetrics& fontMetrics = fontData->getFontMetrics(); // FIXME: Need to turn off font smoothing. const ComputedStyle* computedStyle = 0; TextDirection direction = toTextDirection(state().getDirection(), canvas(), &computedStyle); bool isRTL = direction == RTL; bool override = computedStyle ? isOverride(computedStyle->unicodeBidi()) : false; TextRun textRun(text, 0, 0, TextRun::AllowTrailingExpansion, direction, override); textRun.setNormalizeSpace(true); // Draw the item text at the correct point. FloatPoint location(x, y + getFontBaseline(fontMetrics)); double fontWidth = font.width(textRun); bool useMaxWidth = (maxWidth && *maxWidth < fontWidth); double width = useMaxWidth ? *maxWidth : fontWidth; TextAlign align = state().getTextAlign(); if (align == StartTextAlign) align = isRTL ? RightTextAlign : LeftTextAlign; else if (align == EndTextAlign) align = isRTL ? LeftTextAlign : RightTextAlign; switch (align) { case CenterTextAlign: location.setX(location.x() - width / 2); break; case RightTextAlign: location.setX(location.x() - width); break; default: break; } // The slop built in to this mask rect matches the heuristic used in // FontCGWin.cpp for GDI text. TextRunPaintInfo textRunPaintInfo(textRun); textRunPaintInfo.bounds = FloatRect(location.x() - fontMetrics.height() / 2, location.y() - fontMetrics.ascent() - fontMetrics.lineGap(), width + fontMetrics.height(), fontMetrics.lineSpacing()); if (paintType == CanvasRenderingContext2DState::StrokePaintType) inflateStrokeRect(textRunPaintInfo.bounds); CanvasRenderingContext2DAutoRestoreSkCanvas stateRestorer(this); if (useMaxWidth) { drawingCanvas()->save(); drawingCanvas()->translate(location.x(), location.y()); // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) // still work. drawingCanvas()->scale((fontWidth > 0 ? (width / fontWidth) : 0), 1); location = FloatPoint(); } draw( [&font, this, &textRunPaintInfo, &location]( SkCanvas* c, const SkPaint* paint) // draw lambda { font.drawBidiText(c, textRunPaintInfo, location, Font::UseFallbackIfFontNotReady, cDeviceScaleFactor, *paint); }, [](const SkIRect& rect) // overdraw test lambda { return false; }, textRunPaintInfo.bounds, paintType); }
void SoTexture2::GLRender(SoGLRenderAction *action) // //////////////////////////////////////////////////////////////////////// { SoState * state = action->getState(); if (image.isIgnored() || SoTextureOverrideElement::getImageOverride(state)) return; // Texture being overriden or this node ignored if (isOverride()) { SoTextureOverrideElement::setImageOverride(state, TRUE); } SbVec2s size; int nc; const unsigned char *bytes = image.getValue(size, nc); int numBytes = size[0]*size[1]*nc; float texQuality = SoTextureQualityElement::get(state); if (texQuality == 0 || numBytes == 0 || image.isIgnored()) { SoGLTextureEnabledElement::set(state, FALSE); return; } else { SoGLTextureEnabledElement::set(state, TRUE); } // Check for special cases of 1/2 component texture and model // DECAL or 3/4 component texture and model BLEND; print out // errors in these cases: int m = model.getValue(); if (nc < 3 && m == DECAL) { #ifdef DEBUG SoDebugError::post("SoTexture2::GLRender", "Texture model is DECAL, but texture image" " has only %d components (must be 3 or 4). " "Use imgcopy to convert the image.", nc); #endif SoGLTextureEnabledElement::set(state, FALSE); } else if (nc > 2 && m == BLEND) { #ifdef DEBUG SoDebugError::post("SoTexture2::GLRender", "Texture model is BLEND, but texture image" " has %d components (must be 1 or 2). " "Use imgcopy to convert the image.", nc); #endif SoGLTextureEnabledElement::set(state, FALSE); } else { // This is kind of weird-- the element builds and uses the // display list (which is why we pass it in and assign // it) because it sends the GL calls, and needs to know // the list if the state is popped. But this node must // manage storage and deletion of the display list, since // the list must go away if the node is deleted or the // image is changed. // See if renderList is valid (in the right context, with // the right texture quality): int context = SoGLCacheContextElement::get(state); if (renderList && renderList->getContext() == context && texQuality == renderListQuality) { SoGLTextureImageElement::set( state, this, size, nc, bytes, texQuality, wrapS.getValue(), wrapT.getValue(), m, blendColor.getValue(), renderList); } // Not valid, try to build else { // Free up old list, if necessary: if (renderList) { renderList->unref(state); renderList = NULL; } renderList = SoGLTextureImageElement::set( state, this, size, nc, bytes, texQuality, wrapS.getValue(), wrapT.getValue(), m, blendColor.getValue(), NULL); if (renderList) renderList->ref(); renderListQuality = texQuality; } } }