All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sysalto.render.util.fonts.parsers.AfmParser.scala Maven / Gradle / Ivy

The newest version!
/*
 * ReactiveReports - Free Java /Scala Reporting Library.
 * Copyright (C) 2017 SysAlto Corporation. All rights reserved.
 *
 * This program is part of ReactiveReports.
 *
 * ReactiveReports is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ReactiveReports 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with ReactiveReports.
 * If not, see https://www.gnu.org/licenses/lgpl-3.0.en.html.
 */


package com.sysalto.render.util.fonts.parsers

import com.sysalto.render.util.fonts.parsers.FontParser.FontMetric

import scala.collection.mutable


class AfmParser(fontFile: String) extends FontParser(fontFile)("AfmParser") {
	var fontMetric: FontMetric = null

	private[this] def getValue(list: List[String], key: String): (Int, Int) = {
		val index: Int = list.indexWhere(line => line.startsWith(key))
		if (index == -1) {
			(index, 0)
		} else {
			val line = list(index)
			val tbl = line.trim.split("""\s""")
			(index, tbl(1).toInt)
		}
	}


	def getFontMetric(): FontMetric = {
		if (fontMetric == null) {
			val textList = AfmParser.readFile(s"fonts/${fontFile}.afm")
			val upperHeight = getValue(textList, "CapHeight")._2
			val lowerHeight = getValue(textList, "XHeight")._2
			val metrics = getValue(textList, "StartCharMetrics")
			val lineNbr = metrics._1
			val itemNbr = metrics._2
			val list1 = textList.slice(lineNbr.toInt + 1, lineNbr.toInt + 1 + itemNbr)
			val charList = list1.map(line => {
				val regExpr1 = """C\s+-?\d+\s+;\s+WX\s+(\d+)\s+;\s+N\s+(\S+).*""".r
				val regExpr1(width, name) = line.trim
				name -> (width.toFloat * 0.001).toFloat
			})
			val charList1 = charList.map { case (glyph, code) => AfmParser.glyphDef.glypMap(glyph) -> code }.toMap
			fontMetric = new FontMetric(fontFile, charList1, Map(), ((lowerHeight * 0.001).toFloat, (upperHeight * 0.001).toFloat), None)
		}
		fontMetric
	}

	def getStringWidth(str: String, fontMetric: FontMetric): Float = {
		str.toCharArray.map(char => fontMetric.fontWidth(char.toInt)).sum
	}

}

object AfmParser {

	private[this] class GlyphDef(val glypMap: Map[String, Int])

	private def readFile(fileName: String): List[String] = {
		val stream = getClass.getClassLoader.getResourceAsStream(fileName)
		scala.io.Source.fromInputStream(stream)("latin1").getLines().toList
	}

	private def parseGlyph(): GlyphDef = {
		val charMap = scala.collection.mutable.HashMap[String, Int]()
		val content = readFile("fonts/agl-aglfn-master/glyphlist.txt")
		val list1 = content.filter(s => !s.trim.startsWith("#"))
		val list2 = list1.map(line => {
			val tbl = line.split(";")
			val tbl1 = tbl(1).split(" ").toList
			tbl(0) -> tbl1.map(item => Integer.parseInt(item, 16))
		}).toMap
		val result = list2.filter { case (name, list) =>
			list.length == 1
		}.map { case (name, list) => name -> list.head }
		new GlyphDef(result)
	}


	private val glyphDef = parseGlyph()

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy