////---------------------------- /// FFConfigParser::ParseDefault //-------------------------------- // // // Parameters: // // Returns: // qboolean FFConfigParser::ParseDefaults( const char **pos ) { qboolean result = qboolean( pos != NULL ); if ( pos ) { char *token = COM_ParseExt( pos, qtrue ); if ( token[ 0 ] == '{' ) { for ( token = COM_ParseExt( pos, qtrue ) ; token[ 0 ] && token[ 0 ] != '}' && result // fail if any problem ; token = COM_ParseExt( pos, qtrue ) ){ int techType = 0; if ( sscanf( token, "%d", &techType ) ) { TDeviceType &deviceType = mDefaultSet[ techType ]; if ( !deviceType.size() ) { result &= ParseDefault( pos, deviceType ); mDefaultPriority.push_back( techType ); } else { result = qfalse; #ifdef FF_PRINT ConsoleParseError ( "Redefinition of TechType index" , token ); #endif } } else { result = qfalse; #ifdef FF_PRINT ConsoleParseError ( "TechType fields should begin with integers" , token ); #endif } } } else { // expected '{' result = qfalse; } } return result; }
sk_sp<sksg::Gradient> AttachGradient(const Json::Value& obj, AttachContext* ctx) { SkASSERT(obj.isObject()); const auto& stops = obj["g"]; if (!stops.isObject()) return nullptr; const auto stopCount = ParseDefault(stops["p"], -1); if (stopCount < 0) return nullptr; sk_sp<sksg::Gradient> gradient_node; sk_sp<GradientAdapter> adapter; if (ParseDefault(obj["t"], 1) == 1) { auto linear_node = sksg::LinearGradient::Make(); adapter = sk_make_sp<LinearGradientAdapter>(linear_node, stopCount); gradient_node = std::move(linear_node); } else { auto radial_node = sksg::RadialGradient::Make(); adapter = sk_make_sp<RadialGradientAdapter>(radial_node, stopCount); // TODO: highlight, angle gradient_node = std::move(radial_node); } BindProperty<VectorValue>(stops["k"], &ctx->fAnimators, [adapter](const VectorValue& stops) { adapter->setColorStops(stops); }); BindProperty<VectorValue>(obj["s"], &ctx->fAnimators, [adapter](const VectorValue& s) { adapter->setStartPoint(ValueTraits<VectorValue>::As<SkPoint>(s)); }); BindProperty<VectorValue>(obj["e"], &ctx->fAnimators, [adapter](const VectorValue& e) { adapter->setEndPoint(ValueTraits<VectorValue>::As<SkPoint>(e)); }); return gradient_node; }
sk_sp<sksg::PaintNode> AttachStroke(const Json::Value& jstroke, AttachContext* ctx, sk_sp<sksg::PaintNode> stroke_node) { SkASSERT(jstroke.isObject()); if (!stroke_node) return nullptr; stroke_node->setStyle(SkPaint::kStroke_Style); auto width_attached = BindProperty<ScalarValue>(jstroke["w"], &ctx->fAnimators, [stroke_node](const ScalarValue& w) { stroke_node->setStrokeWidth(w); }); if (!width_attached) return nullptr; stroke_node->setStrokeMiter(ParseDefault(jstroke["ml"], 4.0f)); static constexpr SkPaint::Join gJoins[] = { SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join, }; stroke_node->setStrokeJoin(gJoins[SkTPin<int>(ParseDefault(jstroke["lj"], 1) - 1, 0, SK_ARRAY_COUNT(gJoins) - 1)]); static constexpr SkPaint::Cap gCaps[] = { SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap, }; stroke_node->setStrokeCap(gCaps[SkTPin<int>(ParseDefault(jstroke["lc"], 1) - 1, 0, SK_ARRAY_COUNT(gCaps) - 1)]); return stroke_node; }
sk_sp<sksg::GeometryNode> AttachPolystarGeometry(const Json::Value& jstar, AttachContext* ctx) { SkASSERT(jstar.isObject()); static constexpr PolyStarAdapter::Type gTypes[] = { PolyStarAdapter::Type::kStar, // "sy": 1 PolyStarAdapter::Type::kPoly, // "sy": 2 }; const auto type = ParseDefault(jstar["sy"], 0) - 1; if (type < 0 || type >= SkTo<int>(SK_ARRAY_COUNT(gTypes))) { LogFail(jstar, "Unknown polystar type"); return nullptr; } auto path_node = sksg::Path::Make(); auto adapter = sk_make_sp<PolyStarAdapter>(path_node, gTypes[type]); BindProperty<VectorValue>(jstar["p"], &ctx->fAnimators, [adapter](const VectorValue& p) { adapter->setPosition(ValueTraits<VectorValue>::As<SkPoint>(p)); }); BindProperty<ScalarValue>(jstar["pt"], &ctx->fAnimators, [adapter](const ScalarValue& pt) { adapter->setPointCount(pt); }); BindProperty<ScalarValue>(jstar["ir"], &ctx->fAnimators, [adapter](const ScalarValue& ir) { adapter->setInnerRadius(ir); }); BindProperty<ScalarValue>(jstar["or"], &ctx->fAnimators, [adapter](const ScalarValue& otr) { adapter->setOuterRadius(otr); }); BindProperty<ScalarValue>(jstar["is"], &ctx->fAnimators, [adapter](const ScalarValue& is) { adapter->setInnerRoundness(is); }); BindProperty<ScalarValue>(jstar["os"], &ctx->fAnimators, [adapter](const ScalarValue& os) { adapter->setOuterRoundness(os); }); BindProperty<ScalarValue>(jstar["r"], &ctx->fAnimators, [adapter](const ScalarValue& r) { adapter->setRotation(r); }); return path_node; }
std::vector<sk_sp<sksg::GeometryNode>> AttachMergeGeometryEffect( const Json::Value& jmerge, AttachContext* ctx, std::vector<sk_sp<sksg::GeometryNode>>&& geos) { std::vector<sk_sp<sksg::GeometryNode>> merged; static constexpr sksg::Merge::Mode gModes[] = { sksg::Merge::Mode::kMerge, // "mm": 1 sksg::Merge::Mode::kUnion, // "mm": 2 sksg::Merge::Mode::kDifference, // "mm": 3 sksg::Merge::Mode::kIntersect, // "mm": 4 sksg::Merge::Mode::kXOR , // "mm": 5 }; const auto mode = gModes[SkTPin<int>(ParseDefault(jmerge["mm"], 1) - 1, 0, SK_ARRAY_COUNT(gModes) - 1)]; merged.push_back(sksg::Merge::Make(std::move(geos), mode)); return merged; }
/************************************************************* NAME : ParseDefaultFacet DESCRIPTION : Parses the facet for a slot INPUTS : 1) The input logical name 2) The bitmap indicating which facets have already been parsed 3) The slot descriptor to set RETURNS : True if all OK, false otherwise SIDE EFFECTS : Slot set and parsed facet bitmap set NOTES : Syntax: (default ?NONE|<expression>*) (default-dynamic <expression>*) *************************************************************/ static bool ParseDefaultFacet( Environment *theEnv, const char *readSource, char *specbits, SlotDescriptor *slot) { Expression *tmp; bool error, noneSpecified, deriveSpecified; if (TestBitMap(specbits,DEFAULT_BIT)) { PrintErrorID(theEnv,"CLSLTPSR",2,false); WriteString(theEnv,STDERR,"The 'default' facet for slot '"); WriteString(theEnv,STDERR,slot->slotName->name->contents); WriteString(theEnv,STDERR,"' is already specified.\n"); return false; } SetBitMap(specbits,DEFAULT_BIT); error = false; tmp = ParseDefault(theEnv,readSource,true,TestBitMap(specbits,DEFAULT_DYNAMIC_BIT), false,&noneSpecified,&deriveSpecified,&error); if (error == true) return false; if (noneSpecified || deriveSpecified) { if (noneSpecified) { slot->noDefault = 1; slot->defaultSpecified = 1; } else ClearBitMap(specbits,DEFAULT_BIT); } else { slot->defaultValue = PackExpression(theEnv,tmp); ReturnExpression(theEnv,tmp); ExpressionInstall(theEnv,(Expression *) slot->defaultValue); slot->defaultSpecified = 1; } return true; }
std::vector<sk_sp<sksg::GeometryNode>> AttachTrimGeometryEffect( const Json::Value& jtrim, AttachContext* ctx, std::vector<sk_sp<sksg::GeometryNode>>&& geos) { enum class Mode { kMerged, // "m": 1 kSeparate, // "m": 2 } gModes[] = { Mode::kMerged, Mode::kSeparate }; const auto mode = gModes[SkTPin<int>(ParseDefault(jtrim["m"], 1) - 1, 0, SK_ARRAY_COUNT(gModes) - 1)]; std::vector<sk_sp<sksg::GeometryNode>> inputs; if (mode == Mode::kMerged) { inputs.push_back(sksg::Merge::Make(std::move(geos), sksg::Merge::Mode::kMerge)); } else { inputs = std::move(geos); } std::vector<sk_sp<sksg::GeometryNode>> trimmed; trimmed.reserve(inputs.size()); for (const auto& i : inputs) { const auto trimEffect = sksg::TrimEffect::Make(i); trimmed.push_back(trimEffect); const auto adapter = sk_make_sp<TrimEffectAdapter>(std::move(trimEffect)); BindProperty<ScalarValue>(jtrim["s"], &ctx->fAnimators, [adapter](const ScalarValue& s) { adapter->setStart(s); }); BindProperty<ScalarValue>(jtrim["e"], &ctx->fAnimators, [adapter](const ScalarValue& e) { adapter->setEnd(e); }); BindProperty<ScalarValue>(jtrim["o"], &ctx->fAnimators, [adapter](const ScalarValue& o) { adapter->setOffset(o); }); } return trimmed; }
/************************************************************* NAME : ParseDefaultFacet DESCRIPTION : Parses the facet for a slot INPUTS : 1) The input logical name 2) The bitmap indicating which facets have already been parsed 3) The slot descriptor to set RETURNS : TRUE if all OK, FALSE otherwise SIDE EFFECTS : Slot set and parsed facet bitmap set NOTES : Syntax: (default ?NONE|<expression>*) (default-dynamic <expression>*) *************************************************************/ static intBool ParseDefaultFacet( void *theEnv, EXEC_STATUS, char *readSource, char *specbits, SLOT_DESC *slot) { EXPRESSION *tmp; int error,noneSpecified,deriveSpecified; if (TestBitMap(specbits,DEFAULT_BIT)) { PrintErrorID(theEnv,execStatus,"CLSLTPSR",2,FALSE); EnvPrintRouter(theEnv,execStatus,WERROR,"default facet already specified.\n"); return(FALSE); } SetBitMap(specbits,DEFAULT_BIT); error = FALSE; tmp = ParseDefault(theEnv,execStatus,readSource,1,(int) TestBitMap(specbits,DEFAULT_DYNAMIC_BIT), 0,&noneSpecified,&deriveSpecified,&error); if (error == TRUE) return(FALSE); if (noneSpecified || deriveSpecified) { if (noneSpecified) { slot->noDefault = 1; slot->defaultSpecified = 1; } else ClearBitMap(specbits,DEFAULT_BIT); } else { slot->defaultValue = (void *) PackExpression(theEnv,execStatus,tmp); ReturnExpression(theEnv,execStatus,tmp); ExpressionInstall(theEnv,execStatus,(EXPRESSION *) slot->defaultValue); slot->defaultSpecified = 1; } return(TRUE); }
static void ParseStatement (scontext_t owner) { if (StatementIndex == MAX_STATEMENT_DEPTH) { PR_ParseError("statement overflow"); } ContextHistory[StatementIndex++] = owner; if (TK_CHECK(TK_LBRACE)) { ContextLevel += EnterContext[owner]; do { ParseStatement(owner); } while (!TK_CHECK(TK_RBRACE)); ContextLevel -= EnterContext[owner]; StatementIndex--; return; } if (TK_CHECK(TK_SEMICOLON)) { StatementIndex--; return; } if (LX_CheckFetch("return")) { ParseReturn(); StatementIndex--; return; } if (LX_CheckFetch("loop")) { ParseLoop(); StatementIndex--; return; } if (LX_CheckFetch("while")) { ParseWhile(); StatementIndex--; return; } if (LX_CheckFetch("until")) { ParseUntil(); StatementIndex--; return; } if (LX_CheckFetch("do")) { ParseDo(); StatementIndex--; return; } if (LX_CheckFetch("switch")) { ParseSwitch(); StatementIndex--; return; } if (LX_CheckFetch("case")) { if (owner != SCONTEXT_SWITCH) { PR_ParseError("misplaced case"); } ParseCase(); StatementIndex--; return; } if (LX_CheckFetch("break")) { if (BreakAncestor() == false) { PR_ParseError("misplaced break"); } ParseBreak(); StatementIndex--; return; } if (LX_CheckFetch("continue")) { if (ContinueAncestor() == false) { PR_ParseError("misplaced continue"); } ParseContinue(); StatementIndex--; return; } if (LX_CheckFetch("default")) { ParseDefault(); StatementIndex--; return; } if (LX_CheckFetch("thinktime")) { ParseThinktime(); StatementIndex--; return; } if (LX_CheckFetch("local")) { ParseLocalDefs(); StatementIndex--; return; } if (LX_Check("float") || LX_Check("vector") || LX_Check("entity") || LX_Check("string") || LX_Check("void")) { ParseLocalDefs(); StatementIndex--; return; } if (LX_CheckFetch("if")) { ParseIf(); StatementIndex--; return; } EX_Expression(TOP_PRIORITY); LX_Require(";"); StatementIndex--; }
static struct templateSlot *DefinedSlots( void *theEnv, char *readSource, SYMBOL_HN *slotName, int multifieldSlot, struct token *inputToken) { struct templateSlot *newSlot; struct expr *defaultList; int defaultFound = FALSE; int noneSpecified, deriveSpecified; CONSTRAINT_PARSE_RECORD parsedConstraints; /*===========================*/ /* Build the slot container. */ /*===========================*/ newSlot = get_struct(theEnv,templateSlot); newSlot->slotName = slotName; newSlot->defaultList = NULL; newSlot->constraints = GetConstraintRecord(theEnv); if (multifieldSlot) { newSlot->constraints->multifieldsAllowed = TRUE; } newSlot->multislot = multifieldSlot; newSlot->noDefault = FALSE; newSlot->defaultPresent = FALSE; newSlot->defaultDynamic = FALSE; newSlot->next = NULL; /*========================================*/ /* Parse the primitive slot if it exists. */ /*========================================*/ InitializeConstraintParseRecord(&parsedConstraints); GetToken(theEnv,readSource,inputToken); while (inputToken->type != RPAREN) { PPBackup(theEnv); SavePPBuffer(theEnv," "); SavePPBuffer(theEnv,inputToken->printForm); /*================================================*/ /* Slot attributes begin with a left parenthesis. */ /*================================================*/ if (inputToken->type != LPAREN) { SyntaxErrorMessage(theEnv,"deftemplate"); ReturnSlots(theEnv,newSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*=============================================*/ /* The name of the attribute must be a symbol. */ /*=============================================*/ GetToken(theEnv,readSource,inputToken); if (inputToken->type != SYMBOL) { SyntaxErrorMessage(theEnv,"deftemplate"); ReturnSlots(theEnv,newSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*================================================================*/ /* Determine if the attribute is one of the standard constraints. */ /*================================================================*/ if (StandardConstraint(ValueToString(inputToken->value))) { if (ParseStandardConstraint(theEnv,readSource,(ValueToString(inputToken->value)), newSlot->constraints,&parsedConstraints, multifieldSlot) == FALSE) { DeftemplateData(theEnv)->DeftemplateError = TRUE; ReturnSlots(theEnv,newSlot); return(NULL); } } /*=================================================*/ /* else if the attribute is the default attribute, */ /* then get the default list for this slot. */ /*=================================================*/ else if ((strcmp(ValueToString(inputToken->value),"default") == 0) || (strcmp(ValueToString(inputToken->value),"default-dynamic") == 0)) { /*======================================================*/ /* Check to see if the default has already been parsed. */ /*======================================================*/ if (defaultFound) { AlreadyParsedErrorMessage(theEnv,"default attribute",NULL); DeftemplateData(theEnv)->DeftemplateError = TRUE; ReturnSlots(theEnv,newSlot); return(NULL); } newSlot->noDefault = FALSE; /*=====================================================*/ /* Determine whether the default is dynamic or static. */ /*=====================================================*/ if (strcmp(ValueToString(inputToken->value),"default") == 0) { newSlot->defaultPresent = TRUE; newSlot->defaultDynamic = FALSE; } else { newSlot->defaultPresent = FALSE; newSlot->defaultDynamic = TRUE; } /*===================================*/ /* Parse the list of default values. */ /*===================================*/ defaultList = ParseDefault(theEnv,readSource,multifieldSlot,(int) newSlot->defaultDynamic, TRUE,&noneSpecified,&deriveSpecified,&DeftemplateData(theEnv)->DeftemplateError); if (DeftemplateData(theEnv)->DeftemplateError == TRUE) { ReturnSlots(theEnv,newSlot); return(NULL); } /*==================================*/ /* Store the default with the slot. */ /*==================================*/ defaultFound = TRUE; if (deriveSpecified) newSlot->defaultPresent = FALSE; else if (noneSpecified) { newSlot->noDefault = TRUE; newSlot->defaultPresent = FALSE; } newSlot->defaultList = defaultList; } /*============================================*/ /* Otherwise the attribute is an invalid one. */ /*============================================*/ else { SyntaxErrorMessage(theEnv,"slot attributes"); ReturnSlots(theEnv,newSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*===================================*/ /* Begin parsing the next attribute. */ /*===================================*/ GetToken(theEnv,readSource,inputToken); } /*============================*/ /* Return the attribute list. */ /*============================*/ return(newSlot); }
static void ParseOuter (FScanner &sc) { int bracedepth = 0; bool ifskip = false; while (sc.GetString ()) { if (ifskip) { if (bracedepth > 0) { if (sc.Compare ("}")) { bracedepth--; continue; } } else if (sc.Compare ("endif")) { ifskip = false; continue; } if (sc.Compare ("{")) { bracedepth++; } else if (sc.Compare ("}")) { sc.ScriptError ("Too many left braces ('}')"); } } else { switch (sc.MustMatchString (OuterKeywords)) { case OUT_SPLASH: ParseSplash (sc); break; case OUT_TERRAIN: ParseTerrain (sc); break; case OUT_FLOOR: ParseFloor (sc); break; case OUT_DEFAULTTERRAIN: ParseDefault (sc); break; case OUT_IFDOOM: case OUT_IFHERETIC: case OUT_IFHEXEN: case OUT_IFSTRIFE: ifskip = !CheckGame(sc.String+2, true); break; case OUT_ENDIF: break; } } } }
void AnimationBuilder::parseFonts(const skjson::ObjectValue* jfonts, const skjson::ArrayValue* jchars) { // Optional array of font entries, referenced (by name) from text layer document nodes. E.g. // "fonts": { // "list": [ // { // "ascent": 75, // "fClass": "", // "fFamily": "Roboto", // "fName": "Roboto-Regular", // "fPath": "https://fonts.googleapis.com/css?family=Roboto", // "fPath": "", // "fStyle": "Regular", // "fWeight": "", // "origin": 1 // } // ] // }, if (jfonts) { if (const skjson::ArrayValue* jlist = (*jfonts)["list"]) { for (const skjson::ObjectValue* jfont : *jlist) { if (!jfont) { continue; } const skjson::StringValue* jname = (*jfont)["fName"]; const skjson::StringValue* jfamily = (*jfont)["fFamily"]; const skjson::StringValue* jstyle = (*jfont)["fStyle"]; const skjson::StringValue* jpath = (*jfont)["fPath"]; if (!jname || !jname->size() || !jfamily || !jfamily->size() || !jstyle || !jstyle->size()) { this->log(Logger::Level::kError, jfont, "Invalid font."); continue; } const auto& fmgr = fLazyFontMgr.get(); // Typeface fallback order: // 1) externally-loaded font (provided by the embedder) // 2) system font (family/style) // 3) system default sk_sp<SkTypeface> tf = fmgr->makeFromData(fResourceProvider->loadFont(jname->begin(), jpath ? jpath->begin() : nullptr)); if (!tf) { tf.reset(fmgr->matchFamilyStyle(jfamily->begin(), FontStyle(this, jstyle->begin()))); } if (!tf) { this->log(Logger::Level::kError, nullptr, "Could not create typeface for %s|%s.", jfamily->begin(), jstyle->begin()); // Last resort. tf = fmgr->legacyMakeTypeface(nullptr, FontStyle(this, jstyle->begin())); if (!tf) { continue; } } fFonts.set(SkString(jname->begin(), jname->size()), { SkString(jfamily->begin(), jfamily->size()), SkString(jstyle->begin(), jstyle->size()), ParseDefault((*jfont)["ascent"] , 0.0f), std::move(tf) }); } } } // Optional array of glyphs, to be associated with one of the declared fonts. E.g. // "chars": [ // { // "ch": "t", // "data": { // "shapes": [...] // }, // "fFamily": "Roboto", // "size": 50, // "style": "Regular", // "w": 32.67 // } // ] if (jchars) { FontInfo* current_font = nullptr; for (const skjson::ObjectValue* jchar : *jchars) { if (!jchar) { continue; } const skjson::StringValue* jch = (*jchar)["ch"]; if (!jch) { continue; } const skjson::StringValue* jfamily = (*jchar)["fFamily"]; const skjson::StringValue* jstyle = (*jchar)["style"]; // "style", not "fStyle"... const auto* ch_ptr = jch->begin(); const auto ch_len = jch->size(); if (!jfamily || !jstyle || (SkUTF::CountUTF8(ch_ptr, ch_len) != 1)) { this->log(Logger::Level::kError, jchar, "Invalid glyph."); continue; } const auto uni = SkUTF::NextUTF8(&ch_ptr, ch_ptr + ch_len); SkASSERT(uni != -1); const auto* family = jfamily->begin(); const auto* style = jstyle->begin(); // Locate (and cache) the font info. Unlike text nodes, glyphs reference the font by // (family, style) -- not by name :( For now this performs a linear search over *all* // fonts: generally there are few of them, and glyph definitions are font-clustered. // If problematic, we can refactor as a two-level hashmap. if (!current_font || !current_font->matches(family, style)) { current_font = nullptr; fFonts.foreach([&](const SkString& name, FontInfo* finfo) { if (finfo->matches(family, style)) { current_font = finfo; // TODO: would be nice to break early here... } }); if (!current_font) { this->log(Logger::Level::kError, nullptr, "Font not found for codepoint (%d, %s, %s).", uni, family, style); continue; } } // TODO: parse glyphs } } }