Merged in bug/fix_fonts (pull request #23)

Bug/fix fonts

* Work IP

* Work in progress.

* Fix for selection problem
This commit is contained in:
Paulo Veiga 2022-01-03 21:01:16 +00:00
parent 9be9bed811
commit 96b6d16247
18 changed files with 116 additions and 208 deletions

View File

@ -196,10 +196,10 @@ class MultilineTextEditor extends Events {
// Set Editor Style // Set Editor Style
const nodeText = topic.getTextShape(); const nodeText = topic.getTextShape();
const font = nodeText.getFont(); const fontStyle = nodeText.getFontStyle();
font.size = nodeText.getHtmlFontSize(); fontStyle.size = nodeText.getHtmlFontSize();
font.color = nodeText.getColor(); fontStyle.color = nodeText.getColor();
this._setStyle(font); this._setStyle(fontStyle);
const me = this; const me = this;
// Set editor's initial size // Set editor's initial size
@ -229,8 +229,8 @@ class MultilineTextEditor extends Events {
const inputField = this._getTextareaElem(); const inputField = this._getTextareaElem();
// allowed param reassign to avoid risks of existing code relying in this side-effect // allowed param reassign to avoid risks of existing code relying in this side-effect
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
if (!$defined(fontStyle.font)) { if (!$defined(fontStyle.fontFamily)) {
fontStyle.font = 'Arial'; fontStyle.fontFamily = 'Arial';
} }
if (!$defined(fontStyle.style)) { if (!$defined(fontStyle.style)) {
fontStyle.style = 'normal'; fontStyle.style = 'normal';
@ -244,7 +244,7 @@ class MultilineTextEditor extends Events {
/* eslint-enable no-param-reassign */ /* eslint-enable no-param-reassign */
const style = { const style = {
fontSize: `${fontStyle.size}px`, fontSize: `${fontStyle.size}px`,
fontFamily: fontStyle.font, fontFamily: fontStyle.fontFamily,
fontStyle: fontStyle.style, fontStyle: fontStyle.style,
fontWeight: fontStyle.weight, fontWeight: fontStyle.weight,
color: fontStyle.color, color: fontStyle.color,

View File

@ -44,7 +44,7 @@ import LinkEditor from './widget/LinkEditor';
import TopicEventDispatcher, { import TopicEventDispatcher, {
TopicEvent, TopicEvent,
} from './TopicEventDispatcher'; } from './TopicEventDispatcher';
import INodeModel, { import {
TopicShape, TopicShape,
} from './model/INodeModel'; } from './model/INodeModel';
@ -271,7 +271,6 @@ class Topic extends NodeGraph {
return this._outerShape; return this._outerShape;
} }
/** @return text shape */
getTextShape() { getTextShape() {
if (!$defined(this._text)) { if (!$defined(this._text)) {
this._text = this._buildTextShape(false); this._text = this._buildTextShape(false);
@ -404,7 +403,7 @@ class Topic extends NodeGraph {
/** */ /** */
setFontFamily(value, updateModel) { setFontFamily(value, updateModel) {
const textShape = this.getTextShape(); const textShape = this.getTextShape();
textShape.setFontFamily(value); textShape.setFontName(value);
if ($defined(updateModel) && updateModel) { if ($defined(updateModel) && updateModel) {
const model = this.getModel(); const model = this.getModel();
model.setFontFamily(value); model.setFontFamily(value);

View File

@ -161,7 +161,7 @@ class NodeModel extends INodeModel {
* @param {mindplot.model.NodeModel} child * @param {mindplot.model.NodeModel} child
* @throws will throw an error if child is null, undefined or not a NodeModel object * @throws will throw an error if child is null, undefined or not a NodeModel object
*/ */
append(child: NodeModel) { append(child: NodeModel): void {
$assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object'); $assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object');
this._children.push(child); this._children.push(child);
child._parent = this; child._parent = this;

View File

@ -26,6 +26,7 @@ class FontFamilyPanel extends ListToolbarPanel {
'<div id="times" model="Times" class="toolbarPanelLink" style="font-family:times;">Times</div>' '<div id="times" model="Times" class="toolbarPanelLink" style="font-family:times;">Times</div>'
+ '<div id="arial" model="Arial" style="font-family:arial;">Arial</div>' + '<div id="arial" model="Arial" style="font-family:arial;">Arial</div>'
+ '<div id="tahoma" model="Tahoma" style="font-family:tahoma;">Tahoma</div>' + '<div id="tahoma" model="Tahoma" style="font-family:tahoma;">Tahoma</div>'
+ '<div id="tahoma" model="Brush Script MT" style="font-family:\'Brush Script MT\';">Brush Script</div>'
+ '<div id="verdana" model="Verdana" style="font-family:verdana;">Verdana</div>', + '<div id="verdana" model="Verdana" style="font-family:verdana;">Verdana</div>',
); );
return content; return content;

View File

@ -1,84 +0,0 @@
/*
* Copyright [2021] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Toolkit from './Toolkit';
import TransformUtil from './peer/utils/TransformUtils';
class Font {
constructor(fontFamily, textPeer) {
this.peer = Toolkit[`create${fontFamily}Font`]();
this._textPeer = textPeer;
}
getHtmlSize() {
const scale = TransformUtil.workoutScale(this._textPeer);
return this.peer.getHtmlSize(scale);
}
getGraphSize() {
const scale = TransformUtil.workoutScale(this._textPeer);
return this.peer.getGraphSize(scale);
}
getFontScale() {
return TransformUtil.workoutScale(this._textPeer).height;
}
getSize() {
return this.peer.getSize();
}
getStyle() {
return this.peer.getStyle();
}
getWeight() {
return this.peer.getWeight();
}
getFontFamily() {
return this.peer.getFontFamily();
}
setSize(size) {
return this.peer.setSize(size);
}
setStyle(style) {
return this.peer.setStyle(style);
}
setWeight(weight) {
return this.peer.setWeight(weight);
}
getFont() {
return this.peer.getFont();
}
getWidthMargin() {
return this.peer.getWidthMargin();
}
}
Font.ARIAL = 'Arial';
Font.TIMES = 'Times';
Font.TAHOMA = 'Tahoma';
Font.VERDANA = 'Verdana';
export default Font;

View File

@ -18,12 +18,12 @@
import { $assert } from '@wisemapping/core-js'; import { $assert } from '@wisemapping/core-js';
import ElementClass from './ElementClass'; import ElementClass from './ElementClass';
import TransformUtil from './peer/utils/TransformUtils';
import Toolkit from './Toolkit'; import Toolkit from './Toolkit';
import Font from './Font';
class Text extends ElementClass { class Text extends ElementClass {
constructor(attributes) { constructor(attributes) {
const peer = Toolkit.createText(Font); const peer = Toolkit.createText('Arial');
super(peer, attributes); super(peer, attributes);
} }
@ -53,6 +53,10 @@ class Text extends ElementClass {
this.peer.setFont(font, size, style, weight); this.peer.setFont(font, size, style, weight);
} }
setFontName(fontName) {
this.peer.setFontName(fontName);
}
setColor(color) { setColor(color) {
this.peer.setColor(color); this.peer.setColor(color);
} }
@ -69,12 +73,8 @@ class Text extends ElementClass {
this.peer.setWeight(weight); this.peer.setWeight(weight);
} }
setFontFamily(family) { getFontStyle() {
this.peer.setFontFamily(family); return this.peer.getFontStyle();
}
getFont() {
return this.peer.getFont();
} }
setSize(size) { setSize(size) {
@ -82,7 +82,8 @@ class Text extends ElementClass {
} }
getHtmlFontSize() { getHtmlFontSize() {
return this.peer.getHtmlFontSize(); const scale = TransformUtil.workoutScale(this.peer);
return this.peer.getHtmlFontSize(scale);
} }
getWidth() { getWidth() {

View File

@ -29,8 +29,14 @@ import ArialFont from './peer/svg/ArialFont';
import TimesFont from './peer/svg/TimesFont'; import TimesFont from './peer/svg/TimesFont';
import VerdanaFont from './peer/svg/VerdanaFont'; import VerdanaFont from './peer/svg/VerdanaFont';
import TahomaFont from './peer/svg/TahomaFont'; import TahomaFont from './peer/svg/TahomaFont';
import BrushScriptMTFont from './peer/svg/BrushScriptFont';
class Toolkit { class Toolkit {
static createFontByName(fontName) {
const font = fontName.replaceAll(' ', '');
return Toolkit[`create${font}Font`]();
}
static createWorkspace(element) { static createWorkspace(element) {
return new WorkspacePeer(element); return new WorkspacePeer(element);
} }
@ -59,8 +65,9 @@ class Toolkit {
return new ArrowPeer(); return new ArrowPeer();
} }
static createText(Font) { static createText(fontName) {
return new TextPeer(Font); const font = Toolkit.createFontByName(fontName);
return new TextPeer(font);
} }
static createImage() { static createImage() {
@ -86,6 +93,10 @@ class Toolkit {
static createTahomaFont() { static createTahomaFont() {
return new TahomaFont(); return new TahomaFont();
} }
static createBrushScriptMTFont() {
return new BrushScriptMTFont();
}
} }
export default Toolkit; export default Toolkit;

View File

@ -15,21 +15,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import Font from './Font'; import FontPeer from './FontPeer';
class ArialFont extends Font { class ArialFont extends FontPeer {
constructor() { constructor() {
super(); super('Arial');
this._fontFamily = 'Arial';
}
getFontFamily() {
return this._fontFamily;
}
// eslint-disable-next-line class-methods-use-this
getFont() {
return Font.ARIAL;
} }
} }

View File

@ -0,0 +1,27 @@
/*
* Copyright [2021] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import FontPeer from './FontPeer';
class BrushScriptMTFont extends FontPeer {
// eslint-disable-next-line class-methods-use-this
constructor() {
super('Brush Script MT');
}
}
export default BrushScriptMTFont;

View File

@ -17,11 +17,12 @@
*/ */
import { $assert, $defined } from '@wisemapping/core-js'; import { $assert, $defined } from '@wisemapping/core-js';
class Font { class FontPeer {
constructor() { constructor(fontName) {
this._size = 10; this._size = 10;
this._style = 'normal'; this._style = 'normal';
this._weight = 'normal'; this._weight = 'normal';
this._fontName = fontName;
} }
init(args) { init(args) {
@ -89,6 +90,10 @@ class Font {
} }
return result; return result;
} }
getFontName() {
return this._fontName;
}
} }
export default Font; export default FontPeer;

View File

@ -15,21 +15,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import Font from './Font'; import FontPeer from './FontPeer';
class TahomaFont extends Font { class TahomaFont extends FontPeer {
constructor() { constructor() {
super(); super('Verdana');
this._fontFamily = 'Tahoma';
}
getFontFamily() {
return this._fontFamily;
}
// eslint-disable-next-line class-methods-use-this
getFont() {
return Font.TAHOMA;
} }
} }

View File

@ -18,14 +18,14 @@
import { $defined } from '@wisemapping/core-js'; import { $defined } from '@wisemapping/core-js';
import ElementPeer from './ElementPeer'; import ElementPeer from './ElementPeer';
import { getPosition } from '../utils/DomUtils'; import { getPosition } from '../utils/DomUtils';
import Toolkit from '../../Toolkit';
class TextPeer extends ElementPeer { class TextPeer extends ElementPeer {
constructor(Font) { constructor(fontPeer) {
const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'text'); const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'text');
super(svgElement); super(svgElement);
this.Font = Font;
this._position = { x: 0, y: 0 }; this._position = { x: 0, y: 0 };
this._font = new Font('Arial', this); this._font = fontPeer;
} }
append(element) { append(element) {
@ -84,10 +84,11 @@ class TextPeer extends ElementPeer {
return getPosition(this._native); return getPosition(this._native);
} }
setFont(font, size, style, weight) { setFont(fontName, size, style, weight) {
if ($defined(font)) { if ($defined(fontName)) {
this._font = new this.Font(font, this); this._font = Toolkit.createFontByName(fontName);
} }
if ($defined(style)) { if ($defined(style)) {
this._font.setStyle(style); this._font.setStyle(style);
} }
@ -101,7 +102,7 @@ class TextPeer extends ElementPeer {
} }
_updateFontStyle() { _updateFontStyle() {
this._native.setAttribute('font-family', this._font.getFontFamily()); this._native.setAttribute('font-family', this._font.getFontName());
this._native.setAttribute('font-size', this._font.getGraphSize()); this._native.setAttribute('font-size', this._font.getGraphSize());
this._native.setAttribute('font-style', this._font.getStyle()); this._native.setAttribute('font-style', this._font.getStyle());
this._native.setAttribute('font-weight', this._font.getWeight()); this._native.setAttribute('font-weight', this._font.getWeight());
@ -134,18 +135,18 @@ class TextPeer extends ElementPeer {
this._updateFontStyle(); this._updateFontStyle();
} }
setFontFamily(family) { setFontName(fontName) {
const oldFont = this._font; const oldFont = this._font;
this._font = new this.Font(family, this); this._font = Toolkit.createFontByName(fontName);
this._font.setSize(oldFont.getSize()); this._font.setSize(oldFont.getSize());
this._font.setStyle(oldFont.getStyle()); this._font.setStyle(oldFont.getStyle());
this._font.setWeight(oldFont.getWeight()); this._font.setWeight(oldFont.getWeight());
this._updateFontStyle(); this._updateFontStyle();
} }
getFont() { getFontStyle() {
return { return {
font: this._font.getFont(), fontFamily: this._font.getFontName(),
size: parseInt(this._font.getSize(), 10), size: parseInt(this._font.getSize(), 10),
style: this._font.getStyle(), style: this._font.getStyle(),
weight: this._font.getWeight(), weight: this._font.getWeight(),
@ -158,22 +159,11 @@ class TextPeer extends ElementPeer {
} }
getWidth() { getWidth() {
let computedWidth; let computedWidth = this._native.getBBox().width;
// Firefox hack for this issue:http://stackoverflow.com/questions/6390065/doing-ajax-updates-in-svg-breaks-getbbox-is-there-a-workaround
try {
computedWidth = this._native.getBBox().width;
// Chrome bug is producing this error, oly during page loading.
// Remove the hack if it works. The issue seems to be
// caused when the element is hidden. I don't know why, but it works ...
if (computedWidth === 0) { if (computedWidth === 0) {
const bbox = this._native.getBBox(); const bbox = this._native.getBBox();
computedWidth = bbox.width; computedWidth = bbox.width;
} }
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
computedWidth = 10;
}
let width = parseInt(computedWidth, 10); let width = parseInt(computedWidth, 10);
width += this._font.getWidthMargin(); width += this._font.getWidthMargin();
@ -181,19 +171,12 @@ class TextPeer extends ElementPeer {
} }
getHeight() { getHeight() {
// Firefox hack for this const computedHeight = this._native.getBBox().height;
// issue:http://stackoverflow.com/questions/6390065/doing-ajax-updates-in-svg-breaks-getbbox-is-there-a-workaround
let computedHeight;
try {
computedHeight = this._native.getBBox().height;
} catch (e) {
computedHeight = 10;
}
return parseInt(computedHeight, 10); return parseInt(computedHeight, 10);
} }
getHtmlFontSize() { getHtmlFontSize(scale) {
return this._font.getHtmlSize(); return this._font.getHtmlSize(scale);
} }
} }

View File

@ -15,21 +15,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import Font from './Font'; import FontPeer from './FontPeer';
class TimesFont extends Font { class TimesFont extends FontPeer {
constructor() { constructor() {
super(); super('Times');
this._fontFamily = 'Times';
}
getFontFamily() {
return this._fontFamily;
}
// eslint-disable-next-line class-methods-use-this
getFont() {
return Font.TIMES;
} }
} }

View File

@ -15,21 +15,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import Font from './Font'; import FontPeer from './FontPeer';
class VerdanaFont extends Font { class VerdanaFont extends FontPeer {
constructor() { constructor() {
super(); super('Verdana');
this._fontFamily = 'Verdana';
}
getFontFamily() {
return this._fontFamily;
}
// eslint-disable-next-line class-methods-use-this
getFont() {
return Font.VERDANA;
} }
} }

View File

@ -25,7 +25,6 @@ import Arrow from './components/Arrow';
import Group from './components/Group'; import Group from './components/Group';
import Rect from './components/Rect'; import Rect from './components/Rect';
import Text from './components/Text'; import Text from './components/Text';
import Font from './components/Font';
import Point from './components/Point'; import Point from './components/Point';
import Image from './components/Image'; import Image from './components/Image';
@ -33,7 +32,6 @@ export {
Arrow, Arrow,
CurvedLine, CurvedLine,
Elipse, Elipse,
Font,
Group, Group,
Image, Image,
Line, Line,

View File

@ -13,6 +13,7 @@
<td>Tahoma</td> <td>Tahoma</td>
<td>Verdana</td> <td>Verdana</td>
<td>Times</td> <td>Times</td>
<td>Brush Script MT</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -32,6 +33,9 @@
<td> <td>
<div id="multi3"></div> <div id="multi3"></div>
</td> </td>
<td>
<div id="multi4"></div>
</td>
</tr> </tr>
<tr> <tr>
<td> <td>
@ -49,6 +53,9 @@
<td> <td>
<div id="amulti3"></div> <div id="amulti3"></div>
</td> </td>
<td>
<div id="amulti4"></div>
</td>
</tr> </tr>
<!--**************************************************************************--> <!--**************************************************************************-->
</tbody> </tbody>

View File

@ -1,11 +1,11 @@
import $ from 'jquery'; import $ from 'jquery';
import { import {
Toolkit, Workspace, Text, Workspace, Text,
} from '../../src'; } from '../../src';
global.$ = $; global.$ = $;
function multiline(text, family, elemId) { function multiline(text, fontName, elemId) {
const workspace = new Workspace(); const workspace = new Workspace();
workspace.setSize('200px', '240px'); workspace.setSize('200px', '240px');
workspace.setCoordSize('200', '240'); workspace.setCoordSize('200', '240');
@ -16,7 +16,7 @@ function multiline(text, family, elemId) {
workspace.append(wText); workspace.append(wText);
wText.setText(text); wText.setText(text);
wText.setFont(family, size, 'bold'); wText.setFont(fontName, size, 'bold');
wText.setPosition(30, 50 * i); wText.setPosition(30, 50 * i);
wText.setColor('blue'); wText.setColor('blue');
}); });
@ -45,11 +45,11 @@ function alignments(text, family, elemId) {
} }
// Multine tests ... // Multine tests ...
['Arial', 'Tahoma', 'Verdana', 'Times'].forEach((family, i) => { ['Arial', 'Tahoma', 'Verdana', 'Times', 'Brush Script MT'].forEach((fontName, i) => {
multiline('This multine text.\nLine 1 :)\nLine2', family, `multi${i}`); multiline('This multine text.\nLine 1 :)\nLine2', fontName, `multi${i}`);
}); });
// Multine tests and alingments .. ... // Multine tests and alingments .. ...
['Arial', 'Tahoma', 'Verdana', 'Times'].forEach((family, i) => { ['Arial', 'Tahoma', 'Verdana', 'Times', 'Brush Script MT'].forEach((fontName, i) => {
alignments('This multine text.\nThis is the long line just because :)\nShort line', family, `amulti${i}`); alignments('This multine text.\nThis is the long line just because :)\nShort line', fontName, `amulti${i}`);
}); });

View File

@ -18,7 +18,7 @@ const textTestHelper = function textTestHelper(coordSize, textval, font, fontSiz
const workspace = new Workspace(); const workspace = new Workspace();
workspace.setSize('300px', '100px'); workspace.setSize('300px', '100px');
workspace.setCoordSize('coordSize', coordSize); workspace.setCoordSize(coordSize, coordSize);
workspace.setCoordOrigin(0, 0); workspace.setCoordOrigin(0, 0);
workspace.addItAsChildTo($(`#${htmlElemId}`)); workspace.addItAsChildTo($(`#${htmlElemId}`));
@ -36,7 +36,7 @@ const textTestHelper = function textTestHelper(coordSize, textval, font, fontSiz
span.setAttribute('id', `textoHTML${iesimo}`); span.setAttribute('id', `textoHTML${iesimo}`);
const textsize = `${textval} - Scale: ${scale.height}`; const textsize = `${textval} - Scale: ${scale.height}`;
const textHtml = document.createTextNode(textsize); const textHtml = document.createTextNode(textsize);
const fontSize = text.getHtmlFontSize(); const fontSize = text.getHtmlFontSize(textsize);
span.append(textHtml); span.append(textHtml);
span.setAttribute('style', `font-weight:${modifier};font-style: ${style}; font-size:${fontSize}pt; font-family: ${font};width:30;height:30;`); span.setAttribute('style', `font-weight:${modifier};font-style: ${style}; font-size:${fontSize}pt; font-family: ${font};width:30;height:30;`);