diff --git a/fonts/GUST-FONT-LICENSE.txt b/fonts/GUST-FONT-LICENSE.txt deleted file mode 100755 index 60b5500..0000000 --- a/fonts/GUST-FONT-LICENSE.txt +++ /dev/null @@ -1,30 +0,0 @@ -% This is a preliminary version (2006-09-30), barring acceptance from -% the LaTeX Project Team and other feedback, of the GUST Font License. -% (GUST is the Polish TeX Users Group, http://www.gust.org.pl) -% -% For the most recent version of this license see -% http://www.gust.org.pl/fonts/licenses/GUST-FONT-LICENSE.txt -% or -% http://tug.org/fonts/licenses/GUST-FONT-LICENSE.txt -% -% This work may be distributed and/or modified under the conditions -% of the LaTeX Project Public License, either version 1.3c of this -% license or (at your option) any later version. -% -% Please also observe the following clause: -% 1) it is requested, but not legally required, that derived works be -% distributed only after changing the names of the fonts comprising this -% work and given in an accompanying "manifest", and that the -% files comprising the Work, as listed in the manifest, also be given -% new names. Any exceptions to this request are also given in the -% manifest. -% -% We recommend the manifest be given in a separate file named -% MANIFEST-.txt, where is some unique identification -% of the font family. If a separate "readme" file accompanies the Work, -% we recommend a name of the form README-.txt. -% -% The latest version of the LaTeX Project Public License is in -% http://www.latex-project.org/lppl.txt and version 1.3c or later -% is part of all distributions of LaTeX version 2006/05/20 or later. - diff --git a/fonts/OFL.txt b/fonts/OFL.txt deleted file mode 100644 index 15435ef..0000000 --- a/fonts/OFL.txt +++ /dev/null @@ -1,103 +0,0 @@ -STIX Font License - -24 May 2010 - -Copyright (c) 2001-2010 by the STI Pub Companies, consisting of the American -Institute of Physics, the American Chemical Society, the American Mathematical -Society, the American Physical Society, Elsevier, Inc., and The Institute of -Electrical and Electronic Engineers, Inc. (www.stixfonts.org), with Reserved -Font Name STIX Fonts, STIX Fonts (TM) is a trademark of The Institute of -Electrical and Electronics Engineers, Inc. - -Portions copyright (c) 1998-2003 by MicroPress, Inc. (www.micropress-inc.com), -with Reserved Font Name TM Math. To obtain additional mathematical fonts, please -contact MicroPress, Inc., 68-30 Harrow Street, Forest Hills, NY 11375, USA, -Phone: (718) 575-1816. - -Portions copyright (c) 1990 by Elsevier, Inc. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - ---------------------------------------------------------------------------- -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ---------------------------------------------------------------------------- - -PREAMBLE - -The goals of the Open Font License (OFL) are to stimulate worldwide development -of collaborative font projects, to support the font creation efforts of academic -and linguistic communities, and to provide a free and open framework in which -fonts may be shared and improved in partnership with others. - -The OFL allows the licensed fonts to be used, studied, modified and redistributed -freely as long as they are not sold by themselves. The fonts, including any -derivative works, can be bundled, embedded, redistributed and/or sold with any -software provided that any reserved names are not used by derivative works. The -fonts and derivatives, however, cannot be released under any other type of license. -The requirement for fonts to remain under this license does not apply to any -document created using the fonts or their derivatives. - -DEFINITIONS - -"Font Software" refers to the set of files released by the Copyright Holder(s) under -this license and clearly marked as such. This may include source files, build -scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the copyright -statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, or -substituting -- in part or in whole -- any of the components of the Original Version, -by changing formats or by porting the Font Software to a new environment. - -"Author" refers to any designer, engineer, programmer, technical writer or other -person who contributed to the Font Software. - -PERMISSION & CONDITIONS - -Permission is hereby granted, free of charge, to any person obtaining a copy of the -Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell -modified and unmodified copies of the Font Software, subject to the following -conditions: - -1) Neither the Font Software nor any of its individual components, in Original or -Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, redistributed -and/or sold with any software, provided that each copy contains the above copyright -notice and this license. These can be included either as stand-alone text files, -human-readable headers or in the appropriate machine-readable metadata fields within -text or binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless -explicit written permission is granted by the corresponding Copyright Holder. This -restriction only applies to the primary font name as presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall -not be used to promote, endorse or advertise any Modified Version, except to -acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with -their explicit written permission. - -5) The Font Software, modified or unmodified, in part or in whole, must be distributed -entirely under this license, and must not be distributed under any other license. The -requirement for fonts to remain under this license does not apply to any document -created using the Font Software. - -TERMINATION - -This license becomes null and void if any of the above conditions are not met. - -DISCLAIMER - -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER -RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR -INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/README-Latin-Modern-Math.txt b/fonts/README-Latin-Modern-Math.txt deleted file mode 100755 index 30c8e60..0000000 --- a/fonts/README-Latin-Modern-Math.txt +++ /dev/null @@ -1,92 +0,0 @@ -########################################################################### -############ Latin Modern Collection of Fonts ############ -########################################################################### - -Font: Latin Modern Math -Authors: Bogus\l{}aw Jackowski, Piotr Strzelczyk and Piotr Pianowski -Version: 1.959 -Date: 5 IX 2014 - -License: - % Copyright 2012--2014 for the Latin Modern math extensions by B. Jackowski, - % P. Strzelczyk and P. Pianowski (on behalf of TeX Users Groups). - % - % This work can be freely used and distributed under - % the GUST Font License (GFL -- see GUST-FONT-LICENSE.txt) - % which is actually an instance of the LaTeX Project Public License - % (LPPL -- see http://www.latex-project.org/lppl.txt). - % - % This work has the maintenance status "maintained". The Current Maintainer - % of this work is Bogus\l{}aw Jackowski, Piotr Strzelczyk and Piotr Pianowski. - % - % This work consists of the files listed - % in the MANIFEST-Latin-Modern-Math.txt file. - -########################################################################### -############ A BRIEF DESCRIPTION OF THE FONT ############ -########################################################################### - -Latin Modern Math is a math companion for the Latin Modern family -of fonts (see http://www.gust.org.pl/projects/e-foundry/latin-modern) in -the OpenType format. - -The math OTF fonts should contain a special table, MATH, described in the -confidential Microsoft document "The MATH table and OpenType Features -for Math Processing". Moreover, they should contain a broad collection -of special characters (see "Draft Unicode Technical Report #25. -UNICODE SUPPORT FOR MATHEMATICS" by Barbara Beeton, Asmus Freytag, -and Murray Sargent III). In particular, math OTF fonts are expected -to contain the following scripts: a basic serif script (regular, bold, -italic and bold italic), a calligraphic script (regular and bold), -a double-struck script, a fraktur script (regular and bold), a sans-serif -script (regular, bold, oblique and bold oblique), and a monospaced script. - -The basic script is, obviously, Latin Modern. Some scripts, however, -are borrowed from other fonts (the current selection, however, may -be subject to change), belonging, however, to the "TeX circle": - - * the calligraphic and fraktur alphabets are excerpted from the renowned - Euler family (http://en.wikipedia.org/wiki/AMS_Euler); - - * the double struck script is excerpted from Alan Jeffrey's bbold font - (http://www.tug.org/texlive/Contents/live/texmf-dist/doc/latex/bbold/bbold.pdf) - - * the sans serif and monospaced alphabets are excerpted from - the Latin Modern Sans and Latin Modern Mono fonts - (http://www.gust.org.pl/projects/e-foundry/latin-modern); - sans serif bold Greek symbols (required by the already mentioned - "Unicode Technical Report #25") were prepared using D.E. Knuth's - font sources with some manual tuning - -The main math component, that is, the math extension, was programmed -from scratch, with an attempt to retain the visual compatiblility -with the original D.E. Knuth's fonts. In particular, all symbols -(with a few exceptions) appearing in the D.E. Knuth's "canonical" fonts -have the same width (rounded) as the corresponding Knuthian ones. - -Note that the members of all the mentioned alphabets, except -the main roman alphabet, should be considerd symbols, not letters; -symbols are not expected to occur in a text stream; instead, -they are expected to appear lonely, perhaps with some embellishments -like subscripts, superscripts, primes, dots above and below, etc. - -To produce the font, MetaType1 and the FontForge library were used: -the Type1 PostScript font containing all relevant characters was -generated with the MetaType1 engine, and the result was converted -into the OTF format with all the necessary data structures by -a Python script employing the FontForge library. - -Recent changes (ver. 1.958 --> ver. 1.959) comprised -mainly interline settings in OTF tables (HHEA and -OS/2) and the correction of unicode slots assigned to -the contour integrals (glyphs `clockwise contour -integral', u+2232, and `anticlockwise contour -integral', u+2233, used to have swapped slots). - - * * * - -The TeX Gyre Math Project was launched and is supported by -TeX USERS GROUPS (CS TUG, DANTE eV, GUST, NTG, TUG India, TUG, UK TUG). -Hearty thanks to the representatives of these groups and also -to all people who helped with their work, comments, ideas, -remarks, bug reports, objections, hints, consolations, etc. diff --git a/fonts/README-TeX-Gyre-Termes-Math.txt b/fonts/README-TeX-Gyre-Termes-Math.txt deleted file mode 100755 index 51565bf..0000000 --- a/fonts/README-TeX-Gyre-Termes-Math.txt +++ /dev/null @@ -1,91 +0,0 @@ -########################################################################### -############ The TeX Gyre Collection of Fonts ############ -########################################################################### - -Font: TeX Gyre Termes Math -Authors: Bogus\l{}aw Jackowski, Piotr Strzelczyk and Piotr Pianowski -Version: 1.543 -Date: 5 IX 2014 - -License: - % Copyright 2012--2014 for the TeX Gyre math extensions by B. Jackowski, - % P. Strzelczyk and P. Pianowski (on behalf of TeX Users Groups). - % - % This work can be freely used and distributed under - % the GUST Font License (GFL -- see GUST-FONT-LICENSE.txt) - % which is actually an instance of the LaTeX Project Public License - % (LPPL -- see http://www.latex-project.org/lppl.txt). - % - % This work has the maintenance status "maintained". The Current Maintainer - % of this work is Bogus\l{}aw Jackowski, Piotr Strzelczyk and Piotr Pianowski. - % - % This work consists of the files listed - % in the MANIFEST-TeX-Gyre-Termes.txt file. - -########################################################################### -############ A BRIEF DESCRIPTION OF THE FONT ############ -########################################################################### - -TeX Gyre Termes Math is a math companion for the TeX Gyre Termes family -of fonts (see http://www.gust.org.pl/projects/e-foundry/tex-gyre/) in -the OpenType format. - -The math OTF fonts should contain a special table, MATH, described in the -confidential Microsoft document "The MATH table and OpenType Features -for Math Processing". Moreover, they should contain a broad collection -of special characters (see "Draft Unicode Technical Report #25. -UNICODE SUPPORT FOR MATHEMATICS" by Barbara Beeton, Asmus Freytag, -and Murray Sargent III). In particular, math OTF scripts are expected -to contain the following scripts: a basic serif script (regular, bold, -italic and bold italic), a calligraphic script (regular and bold), -a double-struck script, a fraktur script (regular and bold), a sans-serif -script (regular, bold, oblique and bold oblique), and a monospaced script. - -The basic script is, obviously, TeX Gyre Termes. Symbols, namely, -calligraphic, double struck, Greek, sans serif bold Greek, and Hebrew, -were drawn from scratch. The main math component, that is, the math -extension, was also programmed from scratch. - -Some scripts, however, are borrowed from other fonts (the current -selection, however, may be subject to change): - - * The fraktur alphabets (regular and bold) is excerpted - from the Leipziger Fraktur replica by Peter Wiegel - ( http://www.peter-wiegel.de/Leipzig.html ) - with the kind permission of the author. - - * The sans serif alphabets (regular, oblique, bold, and - bold oblique) are excerpted from TeX Gyre Heros - http://www.gust.org.pl/projects/e-foundry/tex-gyre/heros - (actually, the sans serif bold Greek symbols are based - on TeX Gyre Heros Greek alphabet). - - * The monospaced alphabet is excerpted from TeX Gyre Cursor - http://www.gust.org.pl/projects/e-foundry/tex-gyre/cursor - -Note that the members of all the mentioned alphabets, except -the main roman alphabet, should be considered symbols, not letters; -symbols are not expected to occur in a text stream; instead, -they are expected to appear lonely, perhaps with some embellishments -like subscripts, superscripts, primes, dots above and below, etc. - -To produce the font, MetaType1 and the FontForge library were used: -the Type1 PostScript font containing all relevant characters was -generated with the MetaType1 engine, and the result was converted -into the OTF format with all the necessary data structures by -a Python script employing the FontForge library. - -Recent changes (ver. 1.502 --> ver. 1.543) comprised -mainly interline settings in OTF tables (HHEA and -OS/2) and the correction of the unicode slots assigned to -contour integrals (glyphs `clockwise contour -integral', u+2232, and `anticlockwise contour -integral', u+2233, used to have swapped slots). - - * * * - -The TeX Gyre Math Project was launched and is supported by -TeX USERS GROUPS (CS TUG, DANTE eV, GUST, NTG, TUG India, TUG, UK TUG). -Hearty thanks to the representatives of these groups and also -to all people who helped with their work, comments, ideas, -remarks, bug reports, objections, hints, consolations, etc. diff --git a/fonts/math_table_to_plist.py b/fonts/math_table_to_plist.py deleted file mode 100644 index f6a82ac..0000000 --- a/fonts/math_table_to_plist.py +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/python -import plistlib -import sys -from fontTools.ttLib import TTFont - -def usage(code): - print 'Usage math_table_to_plist.py ' - sys.exit(code) - -def process_font(font_file, out_file): - font = TTFont(font_file) - math_table = font['MATH'].table - constants = get_constants(math_table) - italic_c = get_italic_correction(math_table) - v_variants = get_v_variants(math_table) - h_variants = get_h_variants(math_table) - assembly = get_v_assembly(math_table) - accents = get_accent_attachments(math_table) - pl = { - "version" : "1.3", - "constants": constants, - "v_variants" : v_variants, - "h_variants" : h_variants, - "italic" : italic_c, - "accents" : accents, - "v_assembly" : assembly } - plistlib.writePlist(pl, out_file) - -def get_constants(math_table): - constants = math_table.MathConstants - if constants is None: - raise 'Cannot find MathConstants in MATH table' - - int_consts = [ 'ScriptPercentScaleDown', - 'ScriptScriptPercentScaleDown', - 'DelimitedSubFormulaMinHeight', - 'DisplayOperatorMinHeight', - 'RadicalDegreeBottomRaisePercent'] - consts = { c : getattr(constants, c) for c in int_consts } - - record_consts = [ 'MathLeading', - 'AxisHeight', - 'AccentBaseHeight', - 'FlattenedAccentBaseHeight', - 'SubscriptShiftDown', - 'SubscriptTopMax', - 'SubscriptBaselineDropMin', - 'SuperscriptShiftUp', - 'SuperscriptShiftUpCramped', - 'SuperscriptBottomMin', - 'SuperscriptBaselineDropMax', - 'SubSuperscriptGapMin', - 'SuperscriptBottomMaxWithSubscript', - 'SpaceAfterScript', - 'UpperLimitGapMin', - 'UpperLimitBaselineRiseMin', - 'LowerLimitGapMin', - 'LowerLimitBaselineDropMin', - 'StackTopShiftUp', - 'StackTopDisplayStyleShiftUp', - 'StackBottomShiftDown', - 'StackBottomDisplayStyleShiftDown', - 'StackGapMin', - 'StackDisplayStyleGapMin', - 'StretchStackTopShiftUp', - 'StretchStackBottomShiftDown', - 'StretchStackGapAboveMin', - 'StretchStackGapBelowMin', - 'FractionNumeratorShiftUp', - 'FractionNumeratorDisplayStyleShiftUp', - 'FractionDenominatorShiftDown', - 'FractionDenominatorDisplayStyleShiftDown', - 'FractionNumeratorGapMin', - 'FractionNumDisplayStyleGapMin', - 'FractionRuleThickness', - 'FractionDenominatorGapMin', - 'FractionDenomDisplayStyleGapMin', - 'SkewedFractionHorizontalGap', - 'SkewedFractionVerticalGap', - 'OverbarVerticalGap', - 'OverbarRuleThickness', - 'OverbarExtraAscender', - 'UnderbarVerticalGap', - 'UnderbarRuleThickness', - 'UnderbarExtraDescender', - 'RadicalVerticalGap', - 'RadicalDisplayStyleVerticalGap', - 'RadicalRuleThickness', - 'RadicalExtraAscender', - 'RadicalKernBeforeDegree', - 'RadicalKernAfterDegree', - ] - consts_2 = { c : getattr(constants, c).Value for c in record_consts } - consts.update(consts_2) - - variants = math_table.MathVariants - consts['MinConnectorOverlap'] = variants.MinConnectorOverlap - return consts - -def get_italic_correction(math_table): - glyph_info = math_table.MathGlyphInfo - if glyph_info is None: - raise "Cannot find MathGlyphInfo in MATH table." - italic = glyph_info.MathItalicsCorrectionInfo - if italic is None: - raise "Cannot find Italic Correction in GlyphInfo" - - glyphs = italic.Coverage.glyphs - count = italic.ItalicsCorrectionCount - records = italic.ItalicsCorrection - italic_dict = {} - for i in xrange(count): - name = glyphs[i] - record = records[i] - if record.DeviceTable is not None: - raise "Don't know how to process device table for italic correction." - italic_dict[name] = record.Value - return italic_dict - -def get_accent_attachments(math_table): - glyph_info = math_table.MathGlyphInfo - if glyph_info is None: - raise "Cannot find MathGlyphInfo in MATH table." - attach = glyph_info.MathTopAccentAttachment - if attach is None: - raise "Cannot find Top Accent Attachment in GlyphInfo" - - glyphs = attach.TopAccentCoverage.glyphs - count = attach.TopAccentAttachmentCount - records = attach.TopAccentAttachment - attach_dict = {} - for i in xrange(count): - name = glyphs[i] - record = records[i] - if record.DeviceTable is not None: - raise "Don't know how to process device table for accent attachment." - attach_dict[name] = record.Value - return attach_dict - -def get_v_variants(math_table): - variants = math_table.MathVariants - vglyphs = variants.VertGlyphCoverage.glyphs - vconstruction = variants.VertGlyphConstruction - count = variants.VertGlyphCount - variant_dict = {} - for i in xrange(count): - name = vglyphs[i] - record = vconstruction[i] - glyph_variants = [x.VariantGlyph for x in - record.MathGlyphVariantRecord] - variant_dict[name] = glyph_variants - return variant_dict - -def get_h_variants(math_table): - variants = math_table.MathVariants - hglyphs = variants.HorizGlyphCoverage.glyphs - hconstruction = variants.HorizGlyphConstruction - count = variants.HorizGlyphCount - variant_dict = {} - for i in xrange(count): - name = hglyphs[i] - record = hconstruction[i] - glyph_variants = [x.VariantGlyph for x in - record.MathGlyphVariantRecord] - variant_dict[name] = glyph_variants - return variant_dict - -def get_v_assembly(math_table): - variants = math_table.MathVariants - vglyphs = variants.VertGlyphCoverage.glyphs - vconstruction = variants.VertGlyphConstruction - count = variants.VertGlyphCount - assembly_dict = {} - for i in xrange(count): - name = vglyphs[i] - record = vconstruction[i] - assembly = record.GlyphAssembly - if assembly is not None: - # There is an assembly for this glyph - italic = assembly.ItalicsCorrection.Value - parts = [part_dict(part) for part in assembly.PartRecords] - assembly_dict[name] = { - "italic" : assembly.ItalicsCorrection.Value, - "parts" : parts } - return assembly_dict - -def part_dict(part): - return { - "glyph": part.glyph, - "startConnector" : part.StartConnectorLength, - "endConnector" : part.EndConnectorLength, - "advance" : part.FullAdvance, - "extender" : (part.PartFlags == 1) } - -def main(): - if len(sys.argv) != 3: - usage(1) - font_file = sys.argv[1] - plist_file = sys.argv[2] - process_font(font_file, plist_file) - -if __name__ == '__main__': - main() diff --git a/iosMath.podspec b/iosMath.podspec index 54d8874..166ae7a 100644 --- a/iosMath.podspec +++ b/iosMath.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "iosMath" - s.version = "0.9.5" + s.version = "0.9.6.4" s.summary = "Math equation rendering for iOS and OS X" s.description = <<-DESC iosMath is a library for typesetting math formulas in iOS and OS X using diff --git a/iosMath/LICENSE b/iosMath/LICENSE new file mode 100644 index 0000000..80752fd --- /dev/null +++ b/iosMath/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 MathChat + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/iosMath/README.md b/iosMath/README.md new file mode 100755 index 0000000..fc22cf0 --- /dev/null +++ b/iosMath/README.md @@ -0,0 +1,238 @@ +# iosMath + +[![Build Status](http://img.shields.io/travis/kostub/iosMath.svg?style=flat)](https://travis-ci.org/kostub/iosMath) +[![Version](https://img.shields.io/cocoapods/v/iosMath.svg?style=flat)](http://cocoapods.org/pods/iosMath) +[![License](https://img.shields.io/cocoapods/l/iosMath.svg?style=flat)](http://cocoapods.org/pods/iosMath) +[![Platform](https://img.shields.io/cocoapods/p/iosMath.svg?style=flat)](http://cocoapods.org/pods/iosMath) + +`iosMath` is a library for displaying beautifully rendered math equations +in iOS and MacOS applications. It typesets formulae written using the LaTeX in +a `UILabel` equivalent class. It uses the same typesetting rules as LaTeX and +so the equations are rendered exactly as LaTeX would render them. + +It is similar to [MathJax](https://www.mathjax.org) or +[KaTeX](https://github.com/Khan/KaTeX) for the web but for native iOS or MacOS +applications without having to use a `UIWebView` and Javascript. More +importantly, it is significantly faster than using a `UIWebView`. + +## Examples +Here are screenshots of some formulae that you could render with this +library: + +![Quadratic Formula](img/quadratic.png) + +![Calculus](img/calculus.png) + +![AM-GM](img/amgm.png) + +![Ramanujan Identity](img/ramanujan.png) + +The [EXAMPLES.md](./EXAMPLES.md) file contains more examples. + +## Requirements +`iosMath` works on iOS 6+ or MacOS 10.8+ and requires ARC to build. It depends +on the following Apple frameworks: + +* Foundation.framework +* CoreGraphics.framework +* QuartzCore.framework +* CoreText.framework + +Additionally for iOS it requires: +* UIKit.framework + +Additionally for MacOS it requires: +* AppKit.framework + +## Installation + +### Cocoapods + +iosMath is available through [CocoaPods](http://cocoapods.org). To install +it: + +1. Add a entry for iosMath to your Podfile: `pod 'iosMath'`. +2. Install the pod by running `pod install`. + +### Static library + +You can also add iosMath as a static library to your project or +workspace. + +1. Download the [latest code version](https://github.com/kostub/iosMath/downloads) or add the +repository as a git submodule to your git-tracked project. +2. Open your project in Xcode, then drag and drop + `iosMath.xcodeproj` onto your project or workspace (use the +"Product Navigator view"). +3. Select your target and go to the Build phases tab. In the Link Binary + With Libraries section select the add button. On the sheet find and +add `libIosMath.a`. You might also need to add `iosMath` to +the Target Dependencies list. +4. Add the `MathFontBundle` to the list of `Copy Bundle Resources`. +5. Include IosMath wherever you need it with `#import `. + +## Usage + +The library provides a class `MTMathUILabel` which is a `UIView` that +supports rendering math equations. To display an equation simply create +an `MTMathUILabel` as follows: + +```objective-c +#import "MTMathUILabel.h" + +MTMathUILabel* label = [[MTMathUILabel alloc] init]; +label.latex = @"x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}"; + +``` +Adding `MTMathUILabel` as a sub-view of your `UIView` as will render the +quadratic formula example shown above. + +### Included Features +This is a list of formula types that the library currently supports: + +* Simple algebraic equations +* Fractions and continued fractions +* Exponents and subscripts +* Trigonometric formulae +* Square roots and n-th roots +* Calculus symbos - limits, derivatives, integrals +* Big operators (e.g. product, sum) +* Big delimiters (using \\left and \\right) +* Greek alphabet +* Combinatorics (\\binom, \\choose etc.) +* Geometry symbols (e.g. angle, congruence etc.) +* Ratios, proportions, percents +* Math spacing +* Overline and underline +* Math accents +* Matrices +* Equation alignment +* Change bold, roman, caligraphic and other font styles (\\bf, \\text, etc.) +* Most commonly used math symbols +* Colors + +### Example + +There is a sample app included in this project that shows how to use the +app and the different equations that you can render. To run the sample +app, clone the repository, and run `pod install` first. Then on iOS run the +__iosMathExample__ app. For MacOS run the __MacOSMath__ app. + +### Advanced configuration + +`MTMathUILabel` supports some advanced configuration options: + +##### Math mode + +You can change the mode of the `MTMathUILabel` between Display Mode +(equivalent to `$$` or `\[` in LaTeX) and Text Mode (equivalent to `$` +or `\(` in LaTeX). The default style is Display. To switch to Text +simply: + +```objective-c +label.labelMode = kMTMathUILabelModeText; +``` + +##### Text Alignment +The default alignment of the equations is left. This can be changed to +center or right as follows: + +```objective-c +label.textAlignment = kMTTextAlignmentCenter; +``` + +##### Font size +The default font-size is 20pt. You can change it as follows: + +```objective-c +label.fontSize = 30; +``` +##### Font +The default font is *Latin Modern Math*. This can be changed as: + +```objective-c +label.font = [[MTFontManager fontManager] termesFontWithSize:20]; +``` + +This project has 3 fonts bundled with it, but you can use any OTF math +font. + +##### Color +The default color of the rendered equation is black. You can change +it to any other color as follows: + +```objective-c +label.textColor = [UIColor redColor]; +``` + +It is also possible to set different colors for different parts of the +equation. Just access the `displayList` field and set the `textColor` +on the underlying displays that you want to change the color of. + +##### Custom Commands +You can define your own commands that are not already predefined. This is +similar to macros is LaTeX. To define your own command use: + +```objective-c +[MTMathAtomFactory addLatexSymbol:@"lcm" + value:[MTMathAtomFactory operatorWithName:@"lcm" limits:NO]]; +``` + +This creates a `\lcm` command that can be used in the LaTeX. + +##### Content Insets +The `MTMathUILabel` has `contentInsets` for finer control of placement of the +equation in relation to the view. + +If you need to set it you can do as follows: + +```objective-c +label.contentInsets = UIEdgeInsetsMake(0, 10, 0, 20); +``` + +##### Error handling + +If the LaTeX text given to `MTMathUILabel` is +invalid or if it contains commands that aren't currently supported then +an error message will be displayed instead of the label. + +This error can be programmatically retrieved as `label.error`. If you +prefer not to display anything then set: + +```objective-c +label.displayErrorInline = NO; +``` + +## Future Enhancements + +Note this is not a complete implementation of LaTeX math mode. There are +some important pieces that are missing and will be included in future +updates. This includes: + +* Support for explicit big delimiters (bigl, bigr etc.) +* Addition of missing plain TeX commands + +## Related Projects + +For people looking for things beyond just rendering math, there are two +related projects: + +* [MathEditor](https://github.com/kostub/MathEditor): A WYSIWYG editor + for math equations on iOS. +* [MathSolver](https://github.com/kostub/MathSolver): A library for + solving math equations. + +## License + +iosMath is available under the MIT license. See the [LICENSE](./LICENSE) +file for more info. + +### Fonts +This distribution contains the following fonts. These fonts are +licensed as follows: +* Latin Modern Math: + [GUST Font License](./fonts/GUST-FONT-LICENSE.txt) +* Tex Gyre Termes: + [GUST Font License](./fonts/GUST-FONT-LICENSE.txt) +* [XITS Math](https://github.com/khaledhosny/xits-math): + [Open Font License](./fonts/OFL.txt) diff --git a/iosMath/lib/MTMathAtomFactory.h b/iosMath/lib/MTMathAtomFactory.h index 3bf927d..9fa5dc0 100644 --- a/iosMath/lib/MTMathAtomFactory.h +++ b/iosMath/lib/MTMathAtomFactory.h @@ -64,7 +64,7 @@ FOUNDATION_EXPORT NSString *const MTSymbolDegree; - Chars with special meaning in latex: ^ _ { } \ All other characters will have a non-nil atom returned. */ -+ (nullable MTMathAtom*) atomForCharacter:(unichar) ch; ++ (MTMathAtom*) atomForCharacter:(unichar) ch; /** Returns a `MTMathList` with one atom per character in the given string. This function does not do any LaTeX conversion or interpretation. It simply uses `atomForCharacter` to @@ -74,7 +74,7 @@ FOUNDATION_EXPORT NSString *const MTSymbolDegree; /** Returns an atom with the right type for a given latex symbol (e.g. theta) If the latex symbol is unknown this will return nil. This supports LaTeX aliases as well. */ -+ (nullable MTMathAtom*) atomForLatexSymbolName:(NSString*) symbolName; ++ (MTMathAtom*) atomForLatexSymbolName:(NSString*) symbolName; /** Finds the name of the LaTeX symbol name for the given atom. This function is a reverse of the above function. If no latex symbol name corresponds to the atom, then this returns `nil` @@ -84,7 +84,7 @@ FOUNDATION_EXPORT NSString *const MTSymbolDegree; alias. @note: This function does not convert MathSpaces to latex command names either. */ -+ (nullable NSString*) latexSymbolNameForAtom:(MTMathAtom*) atom; ++ (NSString*) latexSymbolNameForAtom:(MTMathAtom*) atom; /** Define a latex symbol for rendering. This function allows defining custom symbols that are not already present in the default set, or override existing symbols with new meaning. @@ -95,7 +95,7 @@ FOUNDATION_EXPORT NSString *const MTSymbolDegree; /** Returns a list of all supported lated symbols names. */ + (NSArray*) supportedLatexSymbolNames; -/** Returns a large opertor for the given name. If limits is true, limits are set up on +/** Returns a large opertor for the given name. If limits is true, limits are set up on the operator and displyed differently. */ + (MTLargeOperator *)operatorWithName:(NSString *)name limits:(bool) limits; @@ -103,7 +103,7 @@ FOUNDATION_EXPORT NSString *const MTSymbolDegree; such as `grave`, `hat` etc. If the name is not a recognized accent name, this returns nil. The `innerList` of the returned `MTAccent` is nil. */ -+ (nullable MTAccent*) accentWithName:(NSString*) accentName; ++ (MTAccent*) accentWithName:(NSString*) accentName; /** Returns the accent name for the given accent. This is the reverse of the above function. */ @@ -115,14 +115,14 @@ FOUNDATION_EXPORT NSString *const MTSymbolDegree; @note In order to distinguish between the delimiter '|' and the delimiter '\|' the delimiter '\|' the has been renamed to '||'. */ -+(nullable MTMathAtom*) boundaryAtomForDelimiterName:(NSString*) delimiterName; ++(MTMathAtom*) boundaryAtomForDelimiterName:(NSString*) delimiterName; /** Returns the delimiter name for a boundary atom. This is a reverse of the above function. If the atom is not a boundary atom or if the delimiter value is unknown this returns `nil`. @note This is not an exact reverse of the above function. Some delimiters have two names (e.g. `<` and `langle`) and this function always returns the shorter name. */ -+ (nullable NSString*) delimiterNameForBoundaryAtom:(MTMathAtom*) boundary; ++ (NSString*) delimiterNameForBoundaryAtom:(MTMathAtom*) boundary; /** Returns a font style associated with the name. If none is found returns NSNotFound. */ + (MTFontStyle) fontStyleWithName:(NSString*) fontName; @@ -144,7 +144,7 @@ FOUNDATION_EXPORT NSString *const MTSymbolDegree; @note The reason this function returns a `MTMathAtom` and not a `MTMathTable` is because some matrix environments are have builtin delimiters added to the table and hence are returned as inner atoms. */ -+ (nullable MTMathAtom*) tableWithEnvironment:(nullable NSString*) env rows:(NSArray*>*) rows error:(NSError**) error; ++ (MTMathAtom*) tableWithEnvironment:(nullable NSString*) env rows:(NSArray*>*) rows error:(NSError**) error; @end NS_ASSUME_NONNULL_END diff --git a/iosMath/lib/MTMathAtomFactory.m b/iosMath/lib/MTMathAtomFactory.m index 6abc148..bba3fda 100644 --- a/iosMath/lib/MTMathAtomFactory.m +++ b/iosMath/lib/MTMathAtomFactory.m @@ -76,13 +76,10 @@ + (MTLargeOperator *)operatorWithName:(NSString *)name limits:(bool) limits return [[MTLargeOperator alloc] initWithValue:name limits:limits]; } -+ (nullable MTMathAtom *)atomForCharacter:(unichar)ch ++ (MTMathAtom *)atomForCharacter:(unichar)ch { NSString *chStr = [NSString stringWithCharacters:&ch length:1]; - if (ch > 0x0410 && ch < 0x044F){ - // show basic cyrillic alphabet. Latin Modern Math font is not good for cyrillic symbols - return [MTMathAtom atomWithType:kMTMathAtomOrdinary value:chStr]; - } else if (ch < 0x21 || ch > 0x7E) { + if (ch < 0x21 || ch > 0x7E) { // skip non ascii characters and spaces return nil; } else if (ch == '$' || ch == '%' || ch == '#' || ch == '&' || ch == '~' || ch == '\'') { @@ -137,7 +134,7 @@ + (MTMathList *)mathListForCharacters:(NSString *)chars return list; } -+ (nullable MTMathAtom *)atomForLatexSymbolName:(NSString *)symbolName ++ (MTMathAtom *)atomForLatexSymbolName:(NSString *)symbolName { NSParameterAssert(symbolName); NSDictionary* aliases = [MTMathAtomFactory aliases]; @@ -157,7 +154,7 @@ + (nullable MTMathAtom *)atomForLatexSymbolName:(NSString *)symbolName return nil; } -+ (nullable NSString*) latexSymbolNameForAtom:(MTMathAtom*) atom ++ (NSString*) latexSymbolNameForAtom:(MTMathAtom*) atom { if (atom.nucleus.length == 0) { return nil; @@ -184,7 +181,7 @@ + (void)addLatexSymbol:(NSString *)name value:(MTMathAtom *)atom return commands.allKeys; } -+ (nullable MTAccent*) accentWithName:(NSString*) accentName ++ (MTAccent*) accentWithName:(NSString*) accentName { NSDictionary *accents = [MTMathAtomFactory accents]; NSString* accentValue = accents[accentName]; @@ -201,7 +198,7 @@ +(NSString*) accentName:(MTAccent*) accent return dict[accent.nucleus]; } -+ (nullable MTMathAtom *)boundaryAtomForDelimiterName:(NSString *)delimName ++ (MTMathAtom *)boundaryAtomForDelimiterName:(NSString *)delimName { NSDictionary* delims = [MTMathAtomFactory delimiters]; NSString* delimValue = delims[delimName]; @@ -223,7 +220,7 @@ + (NSString*) delimiterNameForBoundaryAtom:(MTMathAtom*) boundary + (MTFontStyle)fontStyleWithName:(NSString *)fontName { NSDictionary* fontStyles = [self fontStyles]; NSNumber* style = fontStyles[fontName]; - if (style == nil) { + if (!style) { return NSNotFound; } return style.integerValue; @@ -279,7 +276,7 @@ + (MTFraction *)fractionWithNumeratorStr:(NSString *)numStr denominatorStr:(NSSt return [self fractionWithNumerator:num denominator:denom]; } -+ (nullable MTMathAtom *)tableWithEnvironment:(NSString *)env rows:(NSArray *> *)rows error:(NSError * _Nullable __autoreleasing *)error ++ (MTMathAtom *)tableWithEnvironment:(NSString *)env rows:(NSArray *> *)rows error:(NSError * _Nullable __autoreleasing *)error { MTMathTable* table = [[MTMathTable alloc] initWithEnvironment:env]; for (int i = 0; i < rows.count; i++) { @@ -333,16 +330,14 @@ + (nullable MTMathAtom *)tableWithEnvironment:(NSString *)env rows:(NSArray* row = table.cells[i]; - if (row.count > 1) { + if (row.count >= 2) { [row[1] insertAtom:spacer atIndex:0]; } } @@ -354,9 +349,7 @@ + (nullable MTMathAtom *)tableWithEnvironment:(NSString *)env rows:(NSArray_colorString = self.colorString; - return op; -} - -- (instancetype)finalized -{ - MTMathColorbox *newInner = [super finalized]; - newInner.innerList = newInner.innerList.finalized; - return newInner; -} - -@end - - #pragma mark - MTMathTable @interface MTMathTable () diff --git a/iosMath/lib/MTMathListBuilder.m b/iosMath/lib/MTMathListBuilder.m index 894609f..c336f23 100644 --- a/iosMath/lib/MTMathListBuilder.m +++ b/iosMath/lib/MTMathListBuilder.m @@ -500,12 +500,6 @@ - (MTMathAtom*) atomForCommand:(NSString*) command mathColor.colorString = [self readColor]; mathColor.innerList = [self buildInternal:true]; return mathColor; - } else if ([command isEqualToString:@"colorbox"]) { - // A color command has 2 arguments - MTMathColorbox* mathColorbox = [[MTMathColorbox alloc] init]; - mathColorbox.colorString = [self readColor]; - mathColorbox.innerList = [self buildInternal:true]; - return mathColorbox; } else { NSString* errorMessage = [NSString stringWithFormat:@"Invalid command \\%@", command]; [self setError:MTParseErrorInvalidCommand message:errorMessage]; @@ -628,7 +622,7 @@ - (MTMathAtom*) buildTable:(NSString*) env firstList:(MTMathList*) firstList row MTEnvProperties* oldEnv = _currentEnv; _currentEnv = [[MTEnvProperties alloc] initWithName:env]; NSInteger currentRow = 0; - NSInteger currentCol = 0; + NSInteger currentCol = 0; // Current Col is actually the next one... NSMutableArray*>* rows = [NSMutableArray array]; rows[0] = [NSMutableArray array]; if (firstList) { @@ -647,11 +641,28 @@ - (MTMathAtom*) buildTable:(NSString*) env firstList:(MTMathList*) firstList row // If there is an error building the list, bail out early. return nil; } + + NSInteger safeCurrentRow = MIN(currentRow, rows.count - 1); + NSInteger safeCurrentCol = MIN(currentCol, rows[safeCurrentRow].count); + if (safeCurrentRow != currentRow) { + [self setError:MTParseErrorMissingEnd message:@"Row Index out of bounds! Don't do this!"]; + return nil; + } + + if (safeCurrentCol != currentCol) { + [self setError:MTParseErrorMissingEnd message:@"Col Index out of bounds! Don't do this!"]; + return nil; + } + rows[currentRow][currentCol] = list; currentCol++; if (_currentEnv.numRows > currentRow) { currentRow = _currentEnv.numRows; - rows[currentRow] = [NSMutableArray array]; + if (rows.count > currentRow) { + rows[currentRow] = [NSMutableArray array]; + } else { + [rows addObject:[NSMutableArray array]]; + } currentCol = 0; } } diff --git a/iosMath/lib/MTMathListIndex.h b/iosMath/lib/MTMathListIndex.h index 9550713..4a0b8c4 100644 --- a/iosMath/lib/MTMathListIndex.h +++ b/iosMath/lib/MTMathListIndex.h @@ -49,9 +49,7 @@ typedef NS_ENUM(unsigned int, MTMathListSubIndexType) { /// The subindex indexes into the radicand (only valid for radicals) kMTSubIndexTypeRadicand, /// The subindex indexes into the degree (only valid for radicals) - kMTSubIndexTypeDegree, - /// The subindex indexes into the inner list (only valid for inner) - kMTSubIndexTypeInner + kMTSubIndexTypeDegree }; diff --git a/iosMath/render/MTFont.m b/iosMath/render/MTFont.m index 84d81a6..b6e64f3 100644 --- a/iosMath/render/MTFont.m +++ b/iosMath/render/MTFont.m @@ -13,10 +13,10 @@ @interface MTFont () -@property (nonatomic, assign) CGFontRef defaultCGFont; -@property (nonatomic, assign) CTFontRef ctFont; -@property (nonatomic, strong) MTFontMathTable* mathTable; -@property (nonatomic, strong) NSDictionary* rawMathTable; +@property (nonatomic) CGFontRef defaultCGFont; +@property (nonatomic) CTFontRef ctFont; +@property (nonatomic) MTFontMathTable* mathTable; +@property (nonatomic) NSDictionary* rawMathTable; @end @@ -25,7 +25,7 @@ @implementation MTFont - (instancetype)initFontWithName:(NSString *)name size:(CGFloat)size { self = [super init]; - if (self != nil) { + if (self ) { // CTFontCreateWithName does not load the complete math font, it only has about half the glyphs of the full math font. // In particular it does not have the math italic characters which breaks our variable rendering. // So we first load a CGFont from the file and then convert it to a CTFont. @@ -46,27 +46,6 @@ - (instancetype)initFontWithName:(NSString *)name size:(CGFloat)size return self; } -- (void)setDefaultCGFont:(CGFontRef)defaultCGFont -{ - if (_defaultCGFont != nil) { - CFRelease(_defaultCGFont); - } - if (defaultCGFont != nil) { - CFRetain(defaultCGFont); - } - _defaultCGFont = defaultCGFont; -} - -- (void)setCtFont:(CTFontRef)ctFont { - if (_ctFont != nil) { - CFRelease(_ctFont); - } - if (ctFont != nil) { - CFRetain(ctFont); - } - _ctFont = ctFont; -} - + (NSBundle*) fontBundle { // Uses bundle for class so that this can be access by the unit tests. @@ -103,7 +82,7 @@ - (CGFloat)fontSize - (void)dealloc { - self.defaultCGFont=nil; - self.ctFont=nil; + CGFontRelease(self.defaultCGFont); + CFRelease(self.ctFont); } @end diff --git a/iosMath/render/MTMathListDisplay.h b/iosMath/render/MTMathListDisplay.h index 3d00b1e..26ccac1 100644 --- a/iosMath/render/MTMathListDisplay.h +++ b/iosMath/render/MTMathListDisplay.h @@ -52,8 +52,7 @@ NS_ASSUME_NONNULL_BEGIN // The local color, if the color was mutated local with the color // command @property (nonatomic, nullable) MTColor *localTextColor; -/// The background color for this display. -@property (nonatomic, nullable) MTColor *localBackgroundColor; + @end /// A rendering of a single CTLine as an MTDisplay @@ -88,9 +87,7 @@ typedef NS_ENUM(unsigned int, MTLinePosition) { /// Positioned at a subscript kMTLinePositionSubscript, /// Positioned at a superscript - kMTLinePositionSuperscript, - /// Positioned at an inner - kMTLinePositionInner + kMTLinePositionSuperscript }; /// Where the line is positioned @@ -187,25 +184,4 @@ typedef NS_ENUM(unsigned int, MTLinePosition) { @end -/// Rendering of an list with delimiters -@interface MTInnerDisplay : MTDisplay - -- (instancetype)init NS_UNAVAILABLE; - -/** A display representing the inner list that can be wrapped in delimiters. - It's position is relative to the parent is not treated as a sub-display. - */ -@property (nonatomic, readonly) MTMathListDisplay* inner; - -/** A display representing the delimiters. Their position is relative - to the parent are not treated as a sub-display. - */ -@property (nonatomic, readonly, nullable) MTDisplay* leftDelimiter; -@property (nonatomic, readonly, nullable) MTDisplay* rightDelimiter; - -/// Denotes the location in the parent MTList. -@property (nonatomic, readonly) NSUInteger index; - -@end - NS_ASSUME_NONNULL_END diff --git a/iosMath/render/MTMathListDisplay.m b/iosMath/render/MTMathListDisplay.m index c609410..ba84f3d 100644 --- a/iosMath/render/MTMathListDisplay.m +++ b/iosMath/render/MTMathListDisplay.m @@ -45,14 +45,6 @@ @implementation MTDisplay - (void)draw:(CGContextRef)context { - if (self.localBackgroundColor != nil) { - CGContextSaveGState(context); - CGContextSetBlendMode(context, kCGBlendModeNormal); - CGContextSetFillColorWithColor(context, self.localBackgroundColor.CGColor); - CGContextFillRect(context, [self displayBounds]); - CGContextRestoreGState(context); - } - } - (CGRect) displayBounds @@ -162,7 +154,6 @@ - (void)dealloc - (void)draw:(CGContextRef)context { - [super draw:context]; CGContextSaveGState(context); CGContextSetTextPosition(context, self.position.x, self.position.y); @@ -221,7 +212,6 @@ - (void)setTextColor:(MTColor *)textColor - (void)draw:(CGContextRef)context { - [super draw:context]; CGContextSaveGState(context); // Make the current position the origin as all the positions of the sub atoms are relative to the origin. @@ -334,7 +324,6 @@ - (void)setTextColor:(MTColor *)textColor - (void)draw:(CGContextRef)context { - [super draw:context]; [_numerator draw:context]; [_denominator draw:context]; @@ -427,7 +416,6 @@ - (void)setTextColor:(MTColor *)textColor - (void)draw:(CGContextRef)context { - [super draw:context]; // draw the radicand & degree at its position [self.radicand draw:context]; [self.degree draw:context]; @@ -486,7 +474,6 @@ - (instancetype)initWithGlpyh:(CGGlyph) glyph range:(NSRange) range font:(MTFont - (void)draw:(CGContextRef)context { - [super draw:context]; CGContextSaveGState(context); [self.textColor setFill]; @@ -543,7 +530,6 @@ - (instancetype)initWithGlyphs:(NSArray *)glyphs offsets:(NSArray> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0]; + return [NSColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0]; } @end diff --git a/iosMath/render/NSView+backgroundColor.m b/iosMath/render/NSView+backgroundColor.m index c5b3d13..0cc6a43 100644 --- a/iosMath/render/NSView+backgroundColor.m +++ b/iosMath/render/NSView+backgroundColor.m @@ -15,9 +15,6 @@ @implementation NSView (backgroundColor) - (NSColor *)backgroundColor { - if (self.layer.backgroundColor == nil) { - return [NSColor clearColor]; - } return [NSColor colorWithCGColor:self.layer.backgroundColor]; } diff --git a/iosMath/render/internal/MTFontMathTable.m b/iosMath/render/internal/MTFontMathTable.m index 927edc6..11cf806 100644 --- a/iosMath/render/internal/MTFontMathTable.m +++ b/iosMath/render/internal/MTFontMathTable.m @@ -481,7 +481,7 @@ - (CGFloat) getTopAccentAdjustment:(CGGlyph) glyph NSDictionary* accents = (NSDictionary*) _mathTable[kAccents]; NSString* glyphName = [self.font getGlyphName:glyph]; NSNumber* val = (NSNumber*) accents[glyphName]; - if (val != nil) { + if (val) { return [self fontUnitsToPt:val.intValue]; } else { // If no top accent is defined then it is the center of the advance width. diff --git a/iosMath/render/internal/MTMathListDisplayInternal.h b/iosMath/render/internal/MTMathListDisplayInternal.h index c63392f..e1e707f 100644 --- a/iosMath/render/internal/MTMathListDisplayInternal.h +++ b/iosMath/render/internal/MTMathListDisplayInternal.h @@ -111,17 +111,3 @@ - (instancetype)initWithAccent:(MTGlyphDisplay*) glyph accentee:(MTMathListDisplay*) accentee range:(NSRange) range NS_DESIGNATED_INITIALIZER; @end - - -@interface MTInnerDisplay () - -- (instancetype) initWithInner:(MTMathListDisplay*) inner leftDelimiter:(MTDisplay*) leftDelimiter rightDelimiter:(MTDisplay*) rightDelimiter atIndex:(NSUInteger) index NS_DESIGNATED_INITIALIZER; - -@property (nonatomic) MTMathListDisplay* inner; - -@property (nonatomic, nullable) MTDisplay* leftDelimiter; -@property (nonatomic, nullable) MTDisplay* rightDelimiter; - -@property (nonatomic) NSUInteger index; - -@end diff --git a/iosMath/render/internal/MTTypesetter.m b/iosMath/render/internal/MTTypesetter.m index 5f56270..93f39c5 100644 --- a/iosMath/render/internal/MTTypesetter.m +++ b/iosMath/render/internal/MTTypesetter.m @@ -48,7 +48,6 @@ typedef NS_ENUM(int, MTInterElementSpaceType) { NSUInteger getInterElementSpaceArrayIndexForType(MTMathAtomType type, BOOL row) { switch (type) { case kMTMathAtomColor: - case kMTMathAtomColorbox: case kMTMathAtomOrdinary: case kMTMathAtomPlaceholder: // A placeholder is treated as ordinary return 0; @@ -630,21 +629,6 @@ - (void) createDisplayAtoms:(NSArray*) preprocessed break; } - case kMTMathAtomColorbox: { - // stash the existing layout - if (_currentLine.length > 0) { - [self addDisplayLine]; - } - MTMathColorbox* colorboxAtom = (MTMathColorbox*) atom; - MTDisplay* display = [MTTypesetter createLineForMathList:colorboxAtom.innerList font:_font style:_style]; - - display.localBackgroundColor = [MTColor colorFromHexString:colorboxAtom.colorString]; - display.position = _currentPosition; - _currentPosition.x += display.width; - [_displayAtoms addObject:display]; - break; - } - case kMTMathAtomRadical: { // stash the existing layout if (_currentLine.length > 0) { @@ -707,7 +691,12 @@ - (void) createDisplayAtoms:(NSArray*) preprocessed } [self addInterElementSpace:prevNode currentType:atom.type]; MTInner* inner = (MTInner*) atom; - MTInnerDisplay* display = [self makeInner:inner atIndex:atom.indexRange.location]; + MTDisplay* display = nil; + if (inner.leftBoundary || inner.rightBoundary) { + display = [self makeLeftRight:inner]; + } else { + display = [MTTypesetter createLineForMathList:inner.innerList font:_font style:_style cramped:_cramped]; + } display.position = _currentPosition; _currentPosition.x += display.width; [_displayAtoms addObject:display]; @@ -1297,7 +1286,7 @@ - (CGGlyph) findGlyph:(CGGlyph) glyph withHeight:(CGFloat) height glyphAscent:(C // Get the bounds for these glyphs CTFontGetBoundingRectsForGlyphs(_styleFont.ctFont, kCTFontHorizontalOrientation, glyphs, bboxes, numVariants); CTFontGetAdvancesForGlyphs(_styleFont.ctFont, kCTFontHorizontalOrientation, glyphs, advances, numVariants); - CGFloat ascent = 0.0, descent = 0.0, width = 0.0; + CGFloat ascent, descent, width; for (int i = 0; i < numVariants; i++) { CGRect bounds = bboxes[i]; width = advances[i].width; @@ -1502,6 +1491,47 @@ - (MTDisplay*) addLimitsToDisplay:(MTDisplay*) display forOperator:(MTLargeOpera #pragma mark Large delimiters +// Delimiter shortfall from plain.tex +static const NSInteger kDelimiterFactor = 901; +static const NSInteger kDelimiterShortfallPoints = 5; + +- (MTDisplay*) makeLeftRight:(MTInner*) inner +{ + NSAssert(inner.leftBoundary || inner.rightBoundary, @"Inner should have a boundary to call this function"); + + MTMathListDisplay* innerListDisplay = [MTTypesetter createLineForMathList:inner.innerList font:_font style:_style cramped:_cramped spaced:YES]; + CGFloat axisHeight = _styleFont.mathTable.axisHeight; + // delta is the max distance from the axis + CGFloat delta = MAX(innerListDisplay.ascent - axisHeight, innerListDisplay.descent + axisHeight); + CGFloat d1 = (delta / 500) * kDelimiterFactor; // This represents atleast 90% of the formula + CGFloat d2 = 2 * delta - kDelimiterShortfallPoints; // This represents a shortfall of 5pt + // The size of the delimiter glyph should cover at least 90% of the formula or + // be at most 5pt short. + CGFloat glyphHeight = MAX(d1, d2); + + NSMutableArray* innerElements = [[NSMutableArray alloc] init]; + CGPoint position = CGPointZero; + if (inner.leftBoundary && inner.leftBoundary.nucleus.length > 0) { + MTDisplay* leftGlyph = [self findGlyphForBoundary:inner.leftBoundary.nucleus withHeight:glyphHeight]; + leftGlyph.position = position; + position.x += leftGlyph.width; + [innerElements addObject:leftGlyph]; + } + + innerListDisplay.position = position; + position.x += innerListDisplay.width; + [innerElements addObject:innerListDisplay]; + + if (inner.rightBoundary && inner.rightBoundary.nucleus.length > 0) { + MTDisplay* rightGlyph = [self findGlyphForBoundary:inner.rightBoundary.nucleus withHeight:glyphHeight]; + rightGlyph.position = position; + position.x += rightGlyph.width; + [innerElements addObject:rightGlyph]; + } + MTMathListDisplay* innerDisplay = [[MTMathListDisplay alloc] initWithDisplays:innerElements range:inner.indexRange]; + return innerDisplay; +} + - (MTDisplay*) findGlyphForBoundary:(NSString*) delimiter withHeight:(CGFloat) glyphHeight { CGFloat glyphAscent, glyphDescent, glyphWidth; @@ -1698,10 +1728,9 @@ - (MTDisplay*) makeTable:(MTMathTable*) table } CGFloat columnWidths[numColumns]; - // NOTE: Using memset to initialize columnWidths array avoids - // Xcode Analyze "Assigned value is garbage or undefined". - // https://stackoverflow.com/questions/21191194/analyzer-warning-assigned-value-is-garbage-or-undefined - memset(columnWidths, 0, sizeof(columnWidths)); + for (int i = 0; i < numColumns; i++) { + columnWidths[i] = 0; + } NSArray*>* displays = [self typesetCells:table columnWidths:columnWidths]; // Position all the columns in each row @@ -1812,46 +1841,4 @@ - (void) positionRows:(NSArray*) rows forTable:(MTMathTable*) table row.position = CGPointMake(row.position.x, row.position.y - shiftDown); } } - -#pragma mark inner - -// Delimiter shortfall from plain.tex -static const NSInteger kDelimiterFactor = 901; -static const NSInteger kDelimiterShortfallPoints = 5; - -- (MTInnerDisplay*) makeInner:(MTInner*) inner atIndex:(NSUInteger) index -{ - NSAssert(inner.leftBoundary || inner.rightBoundary, @"Inner should have a boundary to call this function"); - - MTMathListDisplay* innerListDisplay = [MTTypesetter createLineForMathList:inner.innerList font:_font style:_style cramped:_cramped]; - CGFloat axisHeight = _styleFont.mathTable.axisHeight; - // delta is the max distance from the axis - CGFloat delta = MAX(innerListDisplay.ascent - axisHeight, innerListDisplay.descent + axisHeight); - CGFloat d1 = (delta / 500) * kDelimiterFactor; // This represents atleast 90% of the formula - CGFloat d2 = 2 * delta - kDelimiterShortfallPoints; // This represents a shortfall of 5pt - // The size of the delimiter glyph should cover at least 90% of the formula or - // be at most 5pt short. - CGFloat glyphHeight = MAX(d1, d2); - - MTDisplay* leftDelimiter = nil; - if (inner.leftBoundary && inner.leftBoundary.nucleus.length > 0) { - MTDisplay* leftGlyph = [self findGlyphForBoundary:inner.leftBoundary.nucleus withHeight:glyphHeight]; - if (leftGlyph) { - leftDelimiter = leftGlyph; - } - } - - MTDisplay* rightDelimiter = nil; - if (inner.rightBoundary && inner.rightBoundary.nucleus.length > 0) { - MTDisplay* rightGlyph = [self findGlyphForBoundary:inner.rightBoundary.nucleus withHeight:glyphHeight]; - if (rightGlyph) { - rightDelimiter = rightGlyph; - } - } - - MTInnerDisplay* innerDisplay = [[MTInnerDisplay alloc] initWithInner:innerListDisplay leftDelimiter:leftDelimiter rightDelimiter:rightDelimiter atIndex: index]; - - return innerDisplay; -} - @end