Exemple #1
0
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);
}
Exemple #8
0
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();
}
Exemple #9
0
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();
}
Exemple #13
0
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;

}
Exemple #15
0
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());
}
Exemple #16
0
void UseOverride::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(methodDecl(isOverride()).bind("method"), this);
}
Exemple #17
0
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);
}
Exemple #20
0
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;
	}
    }
}