// Separator line static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) { int c, count = 1; unsigned int i = 0; while (++i) { c = sc.GetRelative(i); if (c == sc.ch) ++count; // hit a terminating character else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) { // Are we a valid HRULE if ((IsNewline(c) || sc.currentPos + i == endPos) && count >= 20 && !HasPrevLineContent(sc)) { sc.SetState(SCE_TXT2TAGS_HRULE); sc.Forward(i); sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); return true; } else { sc.SetState(SCE_TXT2TAGS_DEFAULT); return false; } } } return false; }
/** * Check if the current content context represent a keyword and set the context state if so. */ static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[], int activeState) { int length = sc.LengthCurrent() + 1; // +1 for the next char char* s = new char[length]; sc.GetCurrentLowered(s, length); if (keywordlists[0]->InList(s)) sc.ChangeState(SCE_MYSQL_MAJORKEYWORD | activeState); else if (keywordlists[1]->InList(s)) sc.ChangeState(SCE_MYSQL_KEYWORD | activeState); else if (keywordlists[2]->InList(s)) sc.ChangeState(SCE_MYSQL_DATABASEOBJECT | activeState); else if (keywordlists[3]->InList(s)) sc.ChangeState(SCE_MYSQL_FUNCTION | activeState); else if (keywordlists[5]->InList(s)) sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD | activeState); else if (keywordlists[6]->InList(s)) sc.ChangeState(SCE_MYSQL_USER1 | activeState); else if (keywordlists[7]->InList(s)) sc.ChangeState(SCE_MYSQL_USER2 | activeState); else if (keywordlists[8]->InList(s)) sc.ChangeState(SCE_MYSQL_USER3 | activeState); delete [] s; }
static void ForwardDefaultState(StyleContext& sc, int activeState) { if (activeState == 0) sc.ForwardSetState(SCE_MYSQL_DEFAULT); else sc.ForwardSetState(SCE_MYSQL_HIDDENCOMMAND); }
static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; sc.SetState(SCE_ADA_STRING); sc.Forward(); ColouriseContext(sc, '"', SCE_ADA_STRINGEOL); }
// Test for [=[ ... ]=] delimiters, returns 0 if it's only a [ or ], // return 1 for [[ or ]], returns >=2 for [=[ or ]=] and so on. // The maximum number of '=' characters allowed is 254. static int LongDelimCheck(StyleContext &sc) { int sep = 1; while (sc.GetRelative(sep) == '=' && sep < 0xFF) sep++; if (sc.GetRelative(sep) == sc.ch) return sep; return 0; }
static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) { // Apostrophe meaning is not changed, but the parameter is present for uniformity sc.SetState(SCE_ADA_COMMENTLINE); while (!sc.atLineEnd) { sc.Forward(); } }
static void ColouriseTADS3HTMLTagStart(StyleContext &sc) { sc.SetState(SCE_T3_HTML_TAG); sc.Forward(); if (sc.ch == '/') { sc.Forward(); } while (IsAnHTMLChar(sc.ch)) { sc.Forward(); } }
static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) { while (!sc.atLineEnd && !sc.Match(chEnd)) { sc.Forward(); } if (!sc.atLineEnd) { sc.ForwardSetState(SCE_ADA_DEFAULT); } else { sc.ChangeState(stateEOL); } }
static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; sc.SetState(SCE_ADA_CHARACTER); // Skip the apostrophe and one more character (so that '' is shown as non-terminated and ''' // is handled correctly) sc.Forward(); sc.Forward(); ColouriseContext(sc, '\'', SCE_ADA_CHARACTEREOL); }
// Does the previous line have more than spaces and tabs? static bool HasPrevLineContent(StyleContext &sc) { int i = 0; // Go back to the previous newline while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i))) ; while (--i + sc.currentPos) { if (IsNewline(sc.GetRelative(i))) break; if (!IsASpaceOrTab(sc.GetRelative(i))) return true; } return false; }
void SetUp() override { LOG("SETUP"); if (scene) { return; } auto sceneRelPath = setResourceRoot(sceneFile); auto sceneString = stringFromFile(sceneRelPath.c_str(), PathType::resource); YAML::Node sceneNode; try { sceneNode = YAML::Load(sceneString); } catch (YAML::ParserException e) { LOGE("Parsing scene config '%s'", e.what()); return; } scene = std::make_unique<Scene>(); SceneLoader::loadScene(sceneNode, *scene); styleContext.initFunctions(*scene); styleContext.setGlobalZoom(10); const char* path = "tile.mvt"; std::ifstream resource(path, std::ifstream::ate | std::ifstream::binary); if(!resource.is_open()) { LOGE("Failed to read file at path: %s", path.c_str()); return; } size_t _size = resource.tellg(); resource.seekg(std::ifstream::beg); rawTileData.resize(_size); resource.read(&rawTileData[0], _size); resource.close(); LOG("Initialized TileData"); Tile tile({0,0,0}, s_projection); if (!scene->dataSources().empty()) { source = scene->dataSources()[0]; auto task = source->createTask(tile.getID()); auto& t = dynamic_cast<DownloadTileTask&>(*task); t.rawTileData = std::make_shared<std::vector<char>>(); std::swap(*t.rawTileData, rawTileData); tileData = source->parse(*task, s_projection); } LOG("Ready"); }
static void ColouriseTADS3Number(StyleContext &sc) { int endState = sc.state; bool inHexNumber = false; bool seenE = false; bool seenDot = sc.ch == '.'; sc.SetState(SCE_T3_NUMBER); if (sc.More()) { sc.Forward(); } if (sc.chPrev == '0' && tolower(sc.ch) == 'x') { inHexNumber = true; sc.Forward(); } while (sc.More()) { if (inHexNumber) { if (!IsAHexDigit(sc.ch)) { break; } } else if (!isdigit(sc.ch)) { if (!seenE && tolower(sc.ch) == 'e') { seenE = true; seenDot = true; if (sc.chNext == '+' || sc.chNext == '-') { sc.Forward(); } } else if (!seenDot && sc.ch == '.') { seenDot = true; } else { break; } } sc.Forward(); } sc.SetState(endState); }
static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) { apostropheStartsAttribute = false; sc.SetState(SCE_ADA_LABEL); // Skip "<<" sc.Forward(); sc.Forward(); std::string identifier; while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) { identifier += static_cast<char>(tolower(sc.ch)); sc.Forward(); } // Skip ">>" if (sc.Match('>', '>')) { sc.Forward(); sc.Forward(); } else { sc.ChangeState(SCE_ADA_ILLEGAL); } // If the name is an invalid identifier or a keyword, then make it invalid label if (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) { sc.ChangeState(SCE_ADA_ILLEGAL); } sc.SetState(SCE_ADA_DEFAULT); }
static void ColouriseToEndOfLine(StyleContext &sc, int initState, int endState) { sc.SetState(initState); while (sc.More()) { if (sc.ch == '\\') { sc.Forward(); if (IsEOLSkip(sc)) { return; } } if (IsEOL(sc.ch, sc.chNext)) { sc.SetState(endState); return; } sc.Forward(); } }
void loadScene(const char* sceneFile) { auto sceneRelPath = setResourceRoot(sceneFile); auto sceneString = stringFromFile(sceneRelPath.c_str(), PathType::resource); YAML::Node sceneNode; try { sceneNode = YAML::Load(sceneString); } catch (YAML::ParserException e) { LOGE("Parsing scene config '%s'", e.what()); return; } scene = std::make_unique<Scene>(); SceneLoader::loadScene(sceneNode, *scene); styleContext.initFunctions(*scene); styleContext.setGlobalZoom(0); source = scene->dataSources()[0]; }
void Tile::build(StyleContext& _ctx, const Scene& _scene, const TileData& _data, const DataSource& _source) { const auto& layers = _scene.layers(); _ctx.setGlobal("$zoom", m_id.z); for (auto& style : _scene.styles()) { style->onBeginBuildTile(*this); } for (const auto& datalayer : layers) { if (datalayer.source() != _source.name()) { continue; } for (const auto& collection : _data.layers) { if (!collection.name.empty() && collection.name != datalayer.collection()) { continue; } for (const auto& feat : collection.features) { _ctx.setFeature(feat); std::vector<DrawRule> rules; datalayer.match(feat, _ctx, rules); for (auto& rule : rules) { auto* style = _scene.findStyle(rule.style); if (style) { rule.eval(_ctx); style->buildFeature(*this, feat, rule); } } } } } for (auto& style : _scene.styles()) { style->onEndBuildTile(*this); } for (auto& geometry : m_geometry) { geometry.second->compileVertexBuffer(); } }
static int GlobScan(StyleContext &sc) { // forward scan for a glob-like (...), no whitespace allowed int c, sLen = 0; while ((c = sc.GetRelativeCharacter(++sLen)) != 0) { if (IsASpace(c)) { return 0; } else if (c == ')') { return sLen; } } return 0; }
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; std::string number; sc.SetState(SCE_ADA_NUMBER); // Get all characters up to a delimiter or a separator, including points, but excluding // double points (ranges). while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) { number += static_cast<char>(sc.ch); sc.Forward(); } // Special case: exponent with sign if ((sc.chPrev == 'e' || sc.chPrev == 'E') && (sc.ch == '+' || sc.ch == '-')) { number += static_cast<char>(sc.ch); sc.Forward (); while (!IsSeparatorOrDelimiterCharacter(sc.ch)) { number += static_cast<char>(sc.ch); sc.Forward(); } } if (!IsValidNumber(number)) { sc.ChangeState(SCE_ADA_ILLEGAL); } sc.SetState(SCE_ADA_DEFAULT); }
static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; sc.SetState(SCE_SPICE_IDENTIFIER); std::string word; while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) { word += static_cast<char>(tolower(sc.ch)); sc.Forward(); } if (keywords.InList(word.c_str())) { sc.ChangeState(SCE_SPICE_KEYWORD); if (word != "all") { apostropheStartsAttribute = false; } } else if (keywords2.InList(word.c_str())) { sc.ChangeState(SCE_SPICE_KEYWORD2); if (word != "all") { apostropheStartsAttribute = false; } } else if (keywords3.InList(word.c_str())) { sc.ChangeState(SCE_SPICE_KEYWORD3); if (word != "all") { apostropheStartsAttribute = false; } } sc.SetState(SCE_SPICE_DEFAULT); }
bool DrawRule::eval(const StyleContext& _ctx) { for (auto& param : parameters) { if (param.function >= 0) { if (!_ctx.evalStyle(param.function, param.key, param.value)) { if (StyleParam::isRequired(param.key)){ return false; } } } if (param.stops) { if (StyleParam::isColor(param.key)) { param.value = param.stops->evalColor(_ctx.getGlobalZoom()); } else if (StyleParam::isWidth(param.key)) { param.value = param.stops->evalWidth(_ctx.getGlobalZoom()); } else { param.value = param.stops->evalFloat(_ctx.getGlobalZoom()); } } } return true; }
// Set the state on text section from current to length characters, // then set the rest until the newline to default, except for any characters matching token static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) { sc.SetState(state); sc.Forward(length); sc.SetState(SCE_MARKDOWN_DEFAULT); sc.Forward(); bool started = false; while (sc.More() && !IsNewline(sc.ch)) { if (sc.ch == token && !started) { sc.SetState(state); started = true; } else if (sc.ch != token) { sc.SetState(SCE_MARKDOWN_DEFAULT); started = false; } sc.Forward(); } sc.SetState(SCE_MARKDOWN_LINE_BEGIN); }
void Tile::build(StyleContext& _ctx, const Scene& _scene, const TileData& _data, const DataSource& _source) { // Initialize m_geometry initGeometry(_scene.styles().size()); const auto& layers = _scene.layers(); _ctx.setGlobalZoom(m_id.s); for (auto& style : _scene.styles()) { style->onBeginBuildTile(*this); } DrawRuleMergeSet ruleSet; for (const auto& datalayer : layers) { if (datalayer.source() != _source.name()) { continue; } for (const auto& collection : _data.layers) { if (!collection.name.empty()) { const auto& dlc = datalayer.collections(); bool layerContainsCollection = std::find(dlc.begin(), dlc.end(), collection.name) != dlc.end(); if (!layerContainsCollection) { continue; } } for (const auto& feat : collection.features) { ruleSet.apply(feat, _scene, datalayer, _ctx, *this); } } } for (auto& style : _scene.styles()) { style->onEndBuildTile(*this); } for (auto& geometry : m_geometry) { if (geometry) { geometry->compileVertexBuffer(); } } }
/* * Test the current character to see if it's the START of an EOL sequence; * if so, skip ahead to the last character of the sequence and return true, * and if not just return false. There are a few places where we want to * check to see if a newline sequence occurs at a particular point, but * where a caller expects a subroutine to stop only upon reaching the END * of a newline sequence (in particular, CR-LF on Windows). That's why * IsEOL() above only returns true on CR if the CR isn't followed by an LF * - it doesn't want to admit that there's a newline until reaching the END * of the sequence. We meet both needs by saying that there's a newline * when we see the CR in a CR-LF, but skipping the CR before returning so * that the caller's caller will see that we've stopped at the LF. */ static inline bool IsEOLSkip(StyleContext &sc) { /* test for CR-LF */ if (sc.ch == '\r' && sc.chNext == '\n') { /* got CR-LF - skip the CR and indicate that we're at a newline */ sc.Forward(); return true; } /* * in other cases, we have at most a 1-character newline, so do the * normal IsEOL test */ return IsEOL(sc.ch, sc.chNext); }
static void ColouriseTADS3MsgParam(StyleContext &sc, int &lineState) { int endState = sc.state; int chQuote = '"'; switch (endState) { case SCE_T3_S_STRING: sc.SetState(SCE_T3_MSG_PARAM); sc.Forward(); chQuote = '\''; break; case SCE_T3_D_STRING: case SCE_T3_X_STRING: sc.SetState(SCE_T3_MSG_PARAM); sc.Forward(); break; case SCE_T3_MSG_PARAM: if (lineState&T3_SINGLE_QUOTE) { endState = SCE_T3_S_STRING; chQuote = '\''; } else if (lineState&T3_INT_EXPRESSION) { endState = SCE_T3_X_STRING; } else { endState = SCE_T3_D_STRING; } break; } while (sc.More() && sc.ch != '}' && sc.ch != chQuote) { if (IsEOL(sc.ch, sc.chNext)) { return; } if (sc.ch == '\\') { sc.Forward(); } sc.Forward(); } if (sc.ch == chQuote) { sc.SetState(endState); } else { sc.ForwardSetState(endState); } }
static void ColouriseTADS3Comment(StyleContext &sc, int endState) { sc.SetState(SCE_T3_BLOCK_COMMENT); while (sc.More()) { if (IsEOL(sc.ch, sc.chNext)) { return; } if (sc.Match('*', '/')) { sc.Forward(2); sc.SetState(endState); return; } sc.Forward(); } }
static void ClassifyPascalWord(WordList *keywordlists[], StyleContext &sc, int &curLineState, bool bSmartHighlighting) { WordList& keywords = *keywordlists[0]; char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { if (curLineState & stateInAsm) { if (strcmp(s, "end") == 0 && sc.GetRelative(-4) != '@') { curLineState &= ~stateInAsm; sc.ChangeState(SCE_PAS_WORD); } else { sc.ChangeState(SCE_PAS_ASM); } } else { bool ignoreKeyword = false; if (strcmp(s, "asm") == 0) { curLineState |= stateInAsm; } else if (bSmartHighlighting) { if (strcmp(s, "property") == 0) { curLineState |= stateInProperty; } else if (strcmp(s, "exports") == 0) { curLineState |= stateInExport; } else if (!(curLineState & (stateInProperty | stateInExport)) && strcmp(s, "index") == 0) { ignoreKeyword = true; } else if (!(curLineState & stateInExport) && strcmp(s, "name") == 0) { ignoreKeyword = true; } else if (!(curLineState & stateInProperty) && (strcmp(s, "read") == 0 || strcmp(s, "write") == 0 || strcmp(s, "default") == 0 || strcmp(s, "nodefault") == 0 || strcmp(s, "stored") == 0 || strcmp(s, "implements") == 0 || strcmp(s, "readonly") == 0 || strcmp(s, "writeonly") == 0 || strcmp(s, "add") == 0 || strcmp(s, "remove") == 0)) { ignoreKeyword = true; } } if (!ignoreKeyword) { sc.ChangeState(SCE_PAS_WORD); } } } else if (curLineState & stateInAsm) { sc.ChangeState(SCE_PAS_ASM); } sc.SetState(SCE_PAS_DEFAULT); }
bool DrawRuleMergeSet::match(const Feature& _feature, const SceneLayer& _layer, StyleContext& _ctx) { _ctx.setFeature(_feature); m_matchedRules.clear(); m_queuedLayers.clear(); // If uber layer is marked not visible return immediately if (!_layer.visible()) { return false; } // If the first filter doesn't match, return immediately if (!_layer.filter().eval(_feature, _ctx)) { return false; } m_queuedLayers.push_back(&_layer); // Iterate depth-first over the layer hierarchy while (!m_queuedLayers.empty()) { // Pop a layer off the top of the stack const auto& layer = *m_queuedLayers.back(); m_queuedLayers.pop_back(); // Merge rules from layer into accumulated set mergeRules(layer); // Push each of the layer's matching sublayers onto the stack for (const auto& sublayer : layer.sublayers()) { // Skip matching this sublayer if marked not visible if (!sublayer.visible()) { continue; } if (sublayer.filter().eval(_feature, _ctx)) { m_queuedLayers.push_back(&sublayer); } } } return true; }
// True if can follow ch down to the end with possibly trailing whitespace static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) { unsigned int i = 0; while (sc.GetRelative(++i) == ch) ; // Skip over whitespace while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos) ++i; if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) { sc.Forward(i); sc.ChangeState(state); sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); return true; } else return false; }
static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = sc.Match (')'); sc.SetState(SCE_SPICE_DELIMITER); sc.ForwardSetState(SCE_SPICE_DEFAULT); }
static void ColouriseComment(StyleContext& sc, bool&) { sc.SetState(SCE_SPICE_COMMENTLINE); while (!sc.atLineEnd) { sc.Forward(); } }