/** Reads a length value including a trailing unit specifier and returns it. */ static Length read_length (InputReader &ir) { Length length; ir.skipSpace(); if (!isalpha(ir.peek())) { double val = ir.getDouble(); string unit = isalpha(ir.peek()) ? ir.getString(2) : "pt"; length = Length(val, unit); } return length; }
/** Parses a single line in dvips mapfile format. * @param[in] ir the input stream must be assigned to this reader */ void MapLine::parseDVIPSLine (InputReader &ir) { ir.skipSpace(); if (ir.peek() != '<' && ir.peek() != '"') _psname = ir.getString(); ir.skipSpace(); while (ir.peek() == '<' || ir.peek() == '"') { if (ir.peek() == '<') { ir.get(); if (ir.peek() == '[') ir.get(); string name = ir.getString(); if (name.length() > 4 && name.substr(name.length()-4) == ".enc") _encname = name.substr(0, name.length()-4); else _fontfname = name; } else { // ir.peek() == '"' => list of PS font operators string options = ir.getQuotedString('"'); StringInputBuffer sib(options); BufferInputReader sir(sib); while (!sir.eof()) { double number; if (sir.parseDouble(number)) { // operator with preceding numeric parameter (value opstr) string opstr = sir.getString(); if (opstr == "SlantFont") _slant = number; else if (opstr == "ExtendFont") _extend = number; } else { // operator without parameter => skip for now sir.getString(); } } } ir.skipSpace(); } }
void DvisvgmSpecialHandler::preprocessRawSet (InputReader &ir) { _nestingLevel++; string id = ir.getString(); if (id.empty()) throw SpecialException("definition of unnamed SVG fragment"); if (_nestingLevel > 1) throw SpecialException("nested definition of SVG fragment '" + id + "'"); _currentMacro = _macros.find(id); if (_currentMacro != _macros.end()) { _currentMacro = _macros.end(); throw SpecialException("redefinition of SVG fragment '" + id + "'"); } pair<string, StringVector> entry(id, StringVector()); pair<MacroMap::iterator, bool> state = _macros.insert(entry); _currentMacro = state.first; }
void DvisvgmSpecialHandler::processImg (InputReader &ir, SpecialActions *actions) { if (actions) { const double pt2bp = 72/72.27; double w = ir.getDouble()*pt2bp; double h = ir.getDouble()*pt2bp; string f = ir.getString(); update_bbox(w, h, 0, actions); XMLElementNode *img = new XMLElementNode("image"); img->addAttribute("x", actions->getX()); img->addAttribute("y", actions->getY()); img->addAttribute("width", w); img->addAttribute("height", h); img->addAttribute("xlink:href", f); if (!actions->getMatrix().isIdentity()) img->addAttribute("transform", actions->getMatrix().getSVG()); actions->appendToPage(img); } }
void DvisvgmSpecialHandler::processImg (InputReader &ir, SpecialActions &actions) { try { Length w = read_length(ir); Length h = read_length(ir); string f = ir.getString(); update_bbox(w, h, Length(0), false, actions); auto img = util::make_unique<XMLElement>("image"); img->addAttribute("x", actions.getX()); img->addAttribute("y", actions.getY()); img->addAttribute("width", w.bp()); img->addAttribute("height", h.bp()); img->addAttribute("xlink:href", f); if (!actions.getMatrix().isIdentity()) img->addAttribute("transform", actions.getMatrix().toSVG()); actions.svgTree().appendToPage(std::move(img)); } catch (const UnitException &e) { throw SpecialException(string("dvisvgm:img: ") + e.what()); } }
void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions *actions) { if (_nestingLevel > 0) return; string id = ir.getString(); MacroMap::iterator it = _macros.find(id); if (it == _macros.end()) throw SpecialException("undefined SVG fragment '" + id + "' referenced"); StringVector &defs = it->second; for (StringVector::iterator defs_it=defs.begin(); defs_it != defs.end(); ++defs_it) { char &type = defs_it->at(0); string def = defs_it->substr(1); if ((type == 'P' || type == 'D') && !def.empty()) { expand_constants(def, actions); if (type == 'P') actions->appendToPage(new XMLTextNode(def)); else { // type == 'D' actions->appendToDefs(new XMLTextNode(def)); type = 'L'; // locked } } } }
void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions &actions) { if (_nestingLevel > 0) return; string id = ir.getString(); auto it = _macros.find(id); if (it == _macros.end()) throw SpecialException("undefined SVG fragment '" + id + "' referenced"); StringVector &defvector = it->second; for (string &defstr : defvector) { char &type = defstr[0]; string def = defstr.substr(1); if ((type == 'P' || type == 'D') && !def.empty()) { expand_constants(def, actions); if (type == 'P') _pageParser.parse(def, actions); else { // type == 'D' _defsParser.parse(def, actions); type = 'L'; // locked } } } }
/** Parses a single line in dvipdfmx mapfile format. * @param[in] ir the input stream must be assigned to this reader */ void MapLine::parseDVIPDFMLine (InputReader &ir) { ir.skipSpace(); if (ir.peek() != '-') { _encname = ir.getString(); if (_encname == "default" || _encname == "none") _encname.clear(); } ir.skipSpace(); if (ir.peek() != '-') _fontfname = ir.getString(); if (!_fontfname.empty()) { parseFilenameOptions(_fontfname); } ir.skipSpace(); while (ir.peek() == '-') { ir.get(); int option = ir.get(); if (!isprint(option)) throw MapLineException("option character expected"); ir.skipSpace(); switch (option) { case 's': // slant if (!ir.parseDouble(_slant)) throw_number_expected('s'); break; case 'e': // extend if (!ir.parseDouble(_extend)) throw_number_expected('e'); break; case 'b': // bold if (!ir.parseDouble(_bold)) throw_number_expected('b'); break; case 'r': //remap (deprecated) break; case 'i': // ttc index if (!ir.parseInt(_fontindex, false)) throw_number_expected('i', true); break; case 'p': // UCS plane int dummy; if (!ir.parseInt(dummy, false)) throw_number_expected('p', true); break; case 'u': // to unicode ir.getString(); break; case 'v': // stemV int stemv; if (!ir.parseInt(stemv, true)) throw_number_expected('v', true); break; case 'm': // map single chars ir.skipUntil("-"); break; case 'w': // writing mode (horizontal=0, vertical=1) int vertical; if (!ir.parseInt(vertical, false)) throw_number_expected('w', true); break; default: ostringstream oss; oss << "invalid option: -" << option; throw MapLineException(oss.str()); } ir.skipSpace(); } }