summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp')
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp265
1 files changed, 0 insertions, 265 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp
deleted file mode 100644
index 09b48156307..00000000000
--- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HyperlinkManager.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*************************************************************************
-** HyperlinkManager.cpp **
-** **
-** This file is part of dvisvgm -- a fast DVI to SVG converter **
-** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> **
-** **
-** This program is free software; you can redistribute it and/or **
-** modify it under the terms of the GNU General Public License as **
-** published by the Free Software Foundation; either version 3 of **
-** the License, or (at your option) any later version. **
-** **
-** This program is distributed in the hope that it will be useful, but **
-** WITHOUT ANY WARRANTY; without even the implied warranty of **
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
-** GNU General Public License for more details. **
-** **
-** You should have received a copy of the GNU General Public License **
-** along with this program; if not, see <http://www.gnu.org/licenses/>. **
-*************************************************************************/
-
-#include <sstream>
-#include "HyperlinkManager.hpp"
-#include "Message.hpp"
-#include "SpecialActions.hpp"
-#include "SVGTree.hpp"
-#include "utility.hpp"
-#include "XMLNode.hpp"
-
-using namespace std;
-
-// variable to select the link marker variant (none, underlined, boxed, or colored background)
-HyperlinkManager::MarkerType HyperlinkManager::MARKER_TYPE = MarkerType::LINE;
-Color HyperlinkManager::LINK_BGCOLOR;
-Color HyperlinkManager::LINK_LINECOLOR;
-HyperlinkManager::ColorSource HyperlinkManager::COLORSOURCE = ColorSource::DEFAULT;
-
-
-HyperlinkManager& HyperlinkManager::instance () {
- static HyperlinkManager instance;
- return instance;
-}
-
-
-void HyperlinkManager::addHrefAnchor (const string &uri) {
- if (uri.empty() || uri[0] != '#')
- return;
- string name = uri.substr(1);
- auto it = _namedAnchors.find(name);
- if (it != _namedAnchors.end()) // anchor already defined?
- it->second.referenced = true;
- else {
- int id = static_cast<int>(_namedAnchors.size())+1;
- _namedAnchors.emplace(name, NamedAnchor(0, -id, 0, true));
- }
-}
-
-
-void HyperlinkManager::addNameAchor (const string &name, int pageno) {
- if (name.empty())
- return;
- auto it = _namedAnchors.find(name);
- if (it == _namedAnchors.end()) { // anchor completely undefined?
- int id = static_cast<int>(_namedAnchors.size())+1;
- _namedAnchors.emplace(name, NamedAnchor(pageno, id, 0));
- }
- else if (it->second.id >= 0) // anchor already defined?
- Message::wstream(true) << "named hyperref anchor '" << name << "' redefined\n";
- else {
- // anchor referenced but not defined yet?
- it->second.id *= -1;
- it->second.pageno = pageno;
- }
-}
-
-
-void HyperlinkManager::setActiveNameAnchor (const string &name, SpecialActions &actions) {
- auto it = _namedAnchors.find(name);
- if (it != _namedAnchors.end()) {
- closeAnchor(actions);
- it->second.pos = actions.getY();
- _anchorType = AnchorType::NAME;
- }
-}
-
-
-void HyperlinkManager::createLink (string uri, SpecialActions &actions) {
- closeAnchor(actions);
- string name;
- if (uri[0] == '#') { // reference to named anchor?
- name = uri.substr(1);
- auto it = _namedAnchors.find(name);
- if (it == _namedAnchors.end() || it->second.id < 0)
- Message::wstream(true) << "reference to undefined anchor '" << name << "'\n";
- else {
- int id = it->second.id;
- uri = "#loc"+XMLString(id);
- if (actions.getCurrentPageNumber() != it->second.pageno) {
- ostringstream oss;
- oss << actions.getSVGFilePath(it->second.pageno).relative() << uri;
- uri = oss.str();
- }
- }
- }
- if (!_base.empty() && uri.find("://") != string::npos) {
- if (*_base.rbegin() != '/' && uri[0] != '/' && uri[0] != '#')
- uri = "/" + uri;
- uri = _base + uri;
- }
- auto anchorNode = util::make_unique<XMLElement>("a");
- anchorNode->addAttribute("xlink:href", uri);
- anchorNode->addAttribute("xlink:title", XMLString(name.empty() ? uri : name, false));
- actions.svgTree().pushPageContext(std::move(anchorNode));
- actions.bbox("{anchor}", true); // start computing the bounding box of the linked area
- _depthThreshold = actions.getDVIStackDepth();
- _anchorType = AnchorType::HREF;
-}
-
-
-void HyperlinkManager::closeAnchor (SpecialActions &actions) {
- if (_anchorType == AnchorType::HREF) {
- markLinkedBox(actions);
- actions.svgTree().popPageContext();
- _depthThreshold = 0;
- }
- _anchorType = AnchorType::NONE;
-}
-
-
-void HyperlinkManager::checkNewLine (SpecialActions &actions) {
- if (_anchorType == AnchorType::NONE)
- return;
- // Start a new box if the current depth of the DVI stack underruns
- // the initial threshold which indicates a line break.
- if (actions.getDVIStackDepth() < _depthThreshold) {
- markLinkedBox(actions);
- _depthThreshold = actions.getDVIStackDepth();
- actions.bbox("{anchor}", true); // start a new box on the new line
- }
-}
-
-
-/** Marks a single rectangular area of the linked part of the document with a line or
- * a box so that it's noticeable by the user. Additionally, an invisible rectangle is
- * placed over this area in order to avoid flickering of the mouse cursor when moving
- * it over the hyperlinked area. */
-void HyperlinkManager::markLinkedBox (SpecialActions &actions) {
- const BoundingBox &bbox = actions.bbox("{anchor}");
- if (bbox.width() > 0 && bbox.height() > 0) { // does the bounding box extend in both dimensions?
- if (MARKER_TYPE != MarkerType::NONE) {
- const double linewidth = _linewidth >= 0 ? _linewidth : min(0.5, bbox.height()/15);
- auto rect = util::make_unique<XMLElement>("rect");
- double x = bbox.minX();
- double y = bbox.maxY()+linewidth;
- double w = bbox.width();
- double h = linewidth;
- const Color linecolor = COLORSOURCE == ColorSource::DEFAULT ? actions.getColor() : LINK_LINECOLOR;
- if (MARKER_TYPE == MarkerType::LINE)
- rect->addAttribute("fill", linecolor.svgColorString());
- else {
- const double offset = _linewidth < 0 ? linewidth : 0 ;
- x -= offset;
- y = bbox.minY()-offset;
- w += 2*offset;
- h += bbox.height()+offset;
- if (MARKER_TYPE == MarkerType::BGCOLOR) {
- rect->addAttribute("fill", LINK_BGCOLOR.svgColorString());
- if (COLORSOURCE != ColorSource::DEFAULT) {
- rect->addAttribute("stroke", linecolor.svgColorString());
- rect->addAttribute("stroke-width", linewidth);
- }
- }
- else { // LM_BOX
- rect->addAttribute("fill", "none");
- rect->addAttribute("stroke", linecolor.svgColorString());
- rect->addAttribute("stroke-width", linewidth);
- }
- }
- rect->addAttribute("x", x);
- rect->addAttribute("y", y);
- rect->addAttribute("width", w);
- rect->addAttribute("height", h);
- actions.svgTree().prependToPage(std::move(rect));
- if (MARKER_TYPE == MarkerType::BOX || MARKER_TYPE == MarkerType::BGCOLOR) {
- // slightly enlarge the boxed area
- x -= linewidth/2;
- y -= linewidth/2;
- w += linewidth;
- h += linewidth;
- }
- actions.embed(BoundingBox(x, y, x+w, y+h));
- }
- // Create an invisible rectangle around the linked area so that it's easier to access.
- // This is only necessary when using paths rather than real text elements together with fonts.
- if (!SVGTree::USE_FONTS) {
- auto rect = util::make_unique<XMLElement>("rect");
- rect->addAttribute("x", bbox.minX());
- rect->addAttribute("y", bbox.minY());
- rect->addAttribute("width", bbox.width());
- rect->addAttribute("height", bbox.height());
- rect->addAttribute("fill", "white");
- rect->addAttribute("fill-opacity", 0);
- actions.svgTree().appendToPage(std::move(rect));
- }
- }
-}
-
-
-// Creates SVG views for all collected named anchors defined on a given page.
-void HyperlinkManager::createViews (unsigned pageno, SpecialActions &actions) {
- const BoundingBox &pagebox = actions.bbox();
- for (auto &stranchorpair : _namedAnchors) {
- if (stranchorpair.second.pageno == pageno && stranchorpair.second.referenced) { // current anchor referenced?
- ostringstream oss;
- oss << pagebox.minX() << ' ' << stranchorpair.second.pos << ' '
- << pagebox.width() << ' ' << pagebox.height();
- auto view = util::make_unique<XMLElement>("view");
- view->addAttribute("id", "loc"+XMLString(stranchorpair.second.id));
- view->addAttribute("viewBox", oss.str());
- actions.svgTree().appendToDefs(std::move(view));
- }
- }
- closeAnchor(actions);
-}
-
-
-/** Sets the appearance of the link markers.
- * @param[in] marker string specifying the marker (format: type[:linecolor])
- * @return true on success */
-bool HyperlinkManager::setLinkMarker (const string &marker) {
- string type; // "none", "box", "line", or a background color specifier
- string color; // optional line color specifier
- size_t seppos = marker.find(':');
- if (seppos == string::npos)
- type = marker;
- else {
- type = marker.substr(0, seppos);
- color = marker.substr(seppos+1);
- }
- if (type.empty() || type == "none")
- MARKER_TYPE = MarkerType::NONE;
- else if (type == "line")
- MARKER_TYPE = MarkerType::LINE;
- else if (type == "box")
- MARKER_TYPE = MarkerType::BOX;
- else {
- if (!LINK_BGCOLOR.setPSName(type, false))
- return false;
- MARKER_TYPE = MarkerType::BGCOLOR;
- }
- COLORSOURCE = ColorSource::DEFAULT;
- if (MARKER_TYPE != MarkerType::NONE && !color.empty()) {
- if (!LINK_LINECOLOR.setPSName(color, false))
- return false;
- COLORSOURCE = ColorSource::LINKMARKER;
- }
- return true;
-}
-
-
-void HyperlinkManager::setDefaultLinkColor (Color color) {
- if (COLORSOURCE != ColorSource::LINKMARKER) {
- COLORSOURCE = ColorSource::STATIC;
- LINK_LINECOLOR = color;
- }
-} \ No newline at end of file