Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(text): styles #9081

Closed
wants to merge 40 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
f80702e
Create TextStyles.ts
ShaMan123 Jun 19, 2023
951d771
Update TextStyles.ts
ShaMan123 Jun 19, 2023
b2bf46d
init
ShaMan123 Jun 19, 2023
a47c123
major
ShaMan123 Jun 19, 2023
a976424
Merge branch 'master' into patch-text-styles
ShaMan123 Jun 19, 2023
59359f0
replace methods
ShaMan123 Jun 19, 2023
34c7825
Merge branch 'master' into patch-text-styles
ShaMan123 Jul 9, 2023
f2d26e5
progress
ShaMan123 Jul 9, 2023
75481cb
fix!!!
ShaMan123 Jul 9, 2023
f391fc1
fix!!!
ShaMan123 Jul 9, 2023
de2ce00
update CHANGELOG.md
github-actions[bot] Jul 9, 2023
f628ce7
fix!!!
ShaMan123 Jul 9, 2023
43f90ea
Merge branch 'patch-text-styles' of https://github.com/fabricjs/fabri…
ShaMan123 Jul 9, 2023
1a9d864
Squashed commit of the following:
ShaMan123 Jul 9, 2023
f245088
Update TextStyles.ts
ShaMan123 Jul 9, 2023
8365c0d
Update Text.ts
ShaMan123 Jul 9, 2023
a87c8d3
port createSVGFontFacesMarkup
ShaMan123 Jul 9, 2023
48b693a
Update DraggableTextDelegate.ts
ShaMan123 Jul 9, 2023
6d17ce6
ffffff TS
ShaMan123 Jul 9, 2023
098b493
Update IText.ts
ShaMan123 Jul 9, 2023
3062251
Update DraggableTextDelegate.ts
ShaMan123 Jul 9, 2023
0beb38b
Update TextSVGExportMixin.ts
ShaMan123 Jul 9, 2023
673ac05
cleanup
ShaMan123 Jul 9, 2023
78fad76
Update ITextKeyBehavior.ts
ShaMan123 Jul 9, 2023
03002df
cleanup
ShaMan123 Jul 9, 2023
4e0c7dc
onwards
ShaMan123 Jul 9, 2023
3c27444
more cleanup
ShaMan123 Jul 9, 2023
a14f562
Update text.js
ShaMan123 Jul 9, 2023
3a2edba
more
ShaMan123 Jul 9, 2023
d098d5e
more
ShaMan123 Jul 9, 2023
6f2bbb6
go
ShaMan123 Jul 9, 2023
268a2d6
more
ShaMan123 Jul 9, 2023
bf904cb
jest!!!
ShaMan123 Jul 9, 2023
23ebf2e
better
ShaMan123 Jul 9, 2023
74b99e4
more
ShaMan123 Jul 9, 2023
ed6c723
Update textbox.js
ShaMan123 Jul 9, 2023
1710e46
more
ShaMan123 Jul 9, 2023
5d93943
Update Textbox.ts
ShaMan123 Jul 9, 2023
18a52bc
Update Textbox.ts
ShaMan123 Jul 9, 2023
52ad9c1
fix init
ShaMan123 Jul 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 9 additions & 12 deletions .codesandbox/templates/next/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,16 @@ const IndexPage: NextPage = () => {
originX: 'center',
top: 20,
textAlign: 'center',
styles: fabric.util.stylesFromArray(
[
{
style: {
fontWeight: 'bold',
fontSize: 64,
},
start: 0,
end: 9,
styles: [
{
style: {
fontWeight: 'bold',
fontSize: 64,
},
],
textValue
),
start: 0,
end: 9,
},
],
});
canvas.add(text);
canvas.centerObjectH(text);
Expand Down
21 changes: 9 additions & 12 deletions .codesandbox/templates/vanilla/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,16 @@ const text = new fabric.Textbox(textValue, {
splitByGrapheme: true,
width: 200,
top: 20,
styles: fabric.util.stylesFromArray(
[
{
style: {
fontWeight: 'bold',
fontSize: 64,
},
start: 0,
end: 9,
styles: [
{
style: {
fontWeight: 'bold',
fontSize: 64,
},
],
textValue
),
start: 0,
end: 9,
},
],
});
canvas.add(text);
canvas.centerObjectH(text);
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## [next]

- fix(text): styles [#9081](https://github.com/fabricjs/fabric.js/pull/9081)
- fix(Text): `_getFontDeclaration` [#9079](https://github.com/fabricjs/fabric.js/pull/9079)
- chore(TS): Fix ITextBehaviour enterEditing type [#9075](https://github.com/fabricjs/fabric.js/pull/9075)
- chore(TS): export FabricObjectProps and GroupProps [#9025](https://github.com/fabricjs/fabric.js/pull/9025)
- chore(TS): Replace BaseFabricObject with FabricObject [#9016](https://github.com/fabricjs/fabric.js/pull/9016)
Expand Down
5 changes: 1 addition & 4 deletions fabric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@ export { Polygon } from './src/shapes/Polygon';
export { Text } from './src/shapes/Text/Text';
export { IText } from './src/shapes/IText/IText';
export { Textbox } from './src/shapes/Textbox';
export type {
TextStyleDeclaration,
TextStyle,
} from './src/shapes/Text/StyledText';
export * from './src/shapes/Text/TextStyles';
export { Group } from './src/shapes/Group';
export type {
GroupProps,
Expand Down
2 changes: 1 addition & 1 deletion rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function onwarn(warning, warn) {
!warning.message.includes('sourcemap')) ||
warning.code === 'CIRCULAR_DEPENDENCY'
) {
console.error(chalk.redBright(warning.message));
console.error(chalk.redBright(warning));
if (process.env.CI) {
throw Object.assign(new Error(), warning);
}
Expand Down
47 changes: 13 additions & 34 deletions src/canvas/StaticCanvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1239,49 +1239,28 @@ export class StaticCanvas<
* @return {String}
*/
createSVGFontFacesMarkup(): string {
const objects: FabricObject[] = [],
fontList: Record<string, boolean> = {},
fontPaths = config.fontPaths;
const { fontPaths } = config,
fontList = {} as Record<string, boolean>;

this._objects.forEach(function add(object) {
objects.push(object);
this._objects.forEach(function listFonts(object) {
isTextObject(object) &&
Object.assign(fontList, object.styleManager.getFontFamilyList());
if (isCollection(object)) {
object._objects.forEach(add);
object._objects.forEach(listFonts);
}
});

objects.forEach((obj) => {
if (!isTextObject(obj)) {
return;
}
const { styles, fontFamily } = obj;
if (fontList[fontFamily] || !fontPaths[fontFamily]) {
return;
}
fontList[fontFamily] = true;
if (!styles) {
return;
}
Object.values(styles).forEach((styleRow) => {
Object.values(styleRow).forEach(({ fontFamily = '' }) => {
if (!fontList[fontFamily] && fontPaths[fontFamily]) {
fontList[fontFamily] = true;
}
});
});
});

const fontListMarkup = Object.keys(fontList)
.map(
(fontFamily) =>
`\t\t@font-face {\n\t\t\tfont-family: '${fontFamily}';\n\t\t\tsrc: url('${fontPaths[fontFamily]}');\n\t\t}\n`
.map((fontFamily) =>
fontPaths[fontFamily]
? `\t\t@font-face {\n\t\t\tfont-family: '${fontFamily}';\n\t\t\tsrc: url('${fontPaths[fontFamily]}');\n\t\t}\n`
: ''
)
.join('');

if (fontListMarkup) {
return `\t<style type="text/css"><![CDATA[\n${fontListMarkup}]]></style>\n`;
}
return '';
return fontListMarkup
? `\t<style type="text/css"><![CDATA[\n${fontListMarkup}]]></style>\n`
: '';
}

/**
Expand Down
25 changes: 17 additions & 8 deletions src/shapes/IText/DraggableTextDelegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import type {
import { Point } from '../../Point';
import type { IText } from './IText';
import { setStyle } from '../../util/dom_style';
import { cloneDeep } from '../../util/internals/cloneDeep';
import type { TextStyleDeclaration } from '../Text/StyledText';
import type { TextStyleDeclaration } from '../Text/TextStyles';
import { getDocumentFromElement } from '../../util/dom_misc';
import { NONE } from '../../constants';

Expand Down Expand Up @@ -130,23 +129,33 @@ export class DraggableTextDelegate {
const offset = correction.add(diff).transform(vpt, true);
// prepare instance for drag image snapshot by making all non selected text invisible
const bgc = target.backgroundColor;
const styles = cloneDeep(target.styles);
const styles = target.styleManager.slice();
target.backgroundColor = '';
const styleOverride = {
stroke: 'transparent',
fill: 'transparent',
textBackgroundColor: 'transparent',
};
target.setSelectionStyles(styleOverride, 0, selectionStart);
target.setSelectionStyles(styleOverride, selectionEnd, target.text.length);
target.styleManager.set({
offset: 0,
repeatCount: selectionStart,
style: styleOverride,
});
target.styleManager.set({
offset: selectionEnd,
repeatCount: target._text.length - selectionEnd,
style: styleOverride,
});
// @ts-expect-error protected
target._forceClearCache = true;
target.dirty = true;
const dragImage = target.toCanvasElement({
enableRetinaScaling,
viewportTransform: true,
});
// restore values
target.backgroundColor = bgc;
target.styles = styles;
target.styleManager.reset(styles);
target.dirty = true;
// position drag image offscreen
setStyle(dragImage, {
Expand Down Expand Up @@ -187,10 +196,10 @@ export class DraggableTextDelegate {
'application/fabric',
JSON.stringify({
value: value,
styles: target.getSelectionStyles(
styles: target.styleManager.slice(
selection.selectionStart,
selection.selectionEnd,
true
{ complete: true }
),
})
);
Expand Down
62 changes: 14 additions & 48 deletions src/shapes/IText/IText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
keysMap,
keysMapRtl,
} from './constants';
import type { TFiller } from '../../typedefs';
import { classRegistry } from '../../ClassRegistry';
import type { SerializedTextProps, TextProps } from '../Text/Text';
import {
Expand All @@ -17,6 +16,8 @@
JUSTIFY_RIGHT,
} from '../Text/constants';
import { CENTER, LEFT, RIGHT } from '../../constants';
import { TextStyleDeclaration } from '../Text/TextStyles';

Check failure on line 19 in src/shapes/IText/IText.ts

View workflow job for this annotation

GitHub Actions / lint

All imports in the declaration are only used as types. Use `import type`
import { TProps } from '../Object/types';

Check failure on line 20 in src/shapes/IText/IText.ts

View workflow job for this annotation

GitHub Actions / lint

All imports in the declaration are only used as types. Use `import type`

type CursorBoundaries = {
left: number;
Expand Down Expand Up @@ -103,7 +104,7 @@
* ```
*/
export class IText<
Props extends ITextProps = ITextProps,
Props extends TProps<ITextProps> = Partial<ITextProps>,
SProps extends SerializedITextProps = SerializedITextProps,
EventSpec extends ITextEvents = ITextEvents
>
Expand Down Expand Up @@ -216,7 +217,7 @@
* @param {String} text Text string
* @param {Object} [options] Options object
*/
constructor(text: string, options: object) {
constructor(text: string, options?: Props) {
super(text, options);
this.initBehavior();
}
Expand Down Expand Up @@ -309,33 +310,34 @@
endIndex: number = this.selectionEnd,
complete?: boolean
) {
return super.getSelectionStyles(startIndex, endIndex, complete);
return this.styleManager.slice(startIndex, endIndex, { complete });
}

/**
* Sets style of a current selection, if no selection exist, do not set anything.
* @param {Object} [styles] Styles object
* @param {Object} [style] Styles object
* @param {Number} [startIndex] Start index to get styles at
* @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1
*/
setSelectionStyles(
styles: object,
style: TextStyleDeclaration,
startIndex: number = this.selectionStart || 0,
endIndex: number = this.selectionEnd
) {
return super.setSelectionStyles(styles, startIndex, endIndex);
for (let i = startIndex; i < (endIndex || startIndex); i++) {
this.styleManager.set({ offset: i, style: { ...style } });
}
/* not included in _extendStyles to avoid clearing cache more than once */
this._forceClearCache = true;
}

/**
* Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)
* @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.
* @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.
*/
get2DCursorLocation(
selectionStart = this.selectionStart,
skipWrapping?: boolean
) {
return super.get2DCursorLocation(selectionStart, skipWrapping);
get2DCursorLocation(selectionStart = this.selectionStart) {
return super.get2DCursorLocation(selectionStart);
}

/**
Expand Down Expand Up @@ -650,42 +652,6 @@
}
}

/**
* High level function to know the height of the cursor.
* the currentChar is the one that precedes the cursor
* Returns fontSize of char at the current cursor
* Unused from the library, is for the end user
* @return {Number} Character font size
*/
getCurrentCharFontSize(): number {
const cp = this._getCurrentCharIndex();
return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');
}

/**
* High level function to know the color of the cursor.
* the currentChar is the one that precedes the cursor
* Returns color (fill) of char at the current cursor
* if the text object has a pattern or gradient for filler, it will return that.
* Unused by the library, is for the end user
* @return {String | TFiller} Character color (fill)
*/
getCurrentCharColor(): string | TFiller | null {
const cp = this._getCurrentCharIndex();
return this.getValueOfPropertyAt(cp.l, cp.c, 'fill');
}

/**
* Returns the cursor position for the getCurrent.. functions
* @private
*/
_getCurrentCharIndex() {
const cursorPosition = this.get2DCursorLocation(this.selectionStart, true),
charIndex =
cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;
return { l: cursorPosition.lineIndex, c: charIndex };
}

dispose() {
this._exitEditing();
this.draggableTextDelegate.dispose();
Expand Down
Loading
Loading