Compose material androidx.compose.material.Typography AllCaps Missing? - material-design

I am trying to customise Jetpack Compose
implementation "com.google.android.material:material:$material_version"
I could mimmic the complete XML except for
<item name="android:textAllCaps">true</item>
example
val Typography = Typography(
body1 = TextStyle(
fontFamily = ubuntu,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
letterSpacing = TextUnit(0.03125f, TextUnitType.Sp)
),
h6 = TextStyle(
fontFamily = ubuntu,
fontWeight = FontWeight.Normal,
fontSize = 10.sp,
letterSpacing = TextUnit(0.166666667f, TextUnitType.Sp)
)
...
the parameters in androidx.compose.ui.text.TextStyle.kt I can manupilate is:
val color: Color = Color.Unspecified,
val fontSize: TextUnit = TextUnit.Unspecified,
val fontWeight: FontWeight? = null,
val fontStyle: FontStyle? = null,
val fontSynthesis: FontSynthesis? = null,
val fontFamily: FontFamily? = null,
val fontFeatureSettings: String? = null,
val letterSpacing: TextUnit = TextUnit.Unspecified,
val baselineShift: BaselineShift? = null,
val textGeometricTransform: TextGeometricTransform? = null,
val localeList: LocaleList? = null,
val background: Color = Color.Unspecified,
val textDecoration: TextDecoration? = null,
val shadow: Shadow? = null,
val textAlign: TextAlign? = null,
val textDirection: TextDirection? = null,
val lineHeight: TextUnit = TextUnit.Unspecified,
val textIndent: TextIndent? = null
However I do not see one that allow me to define ALLCAPS

Related

extendscript after effects why isnt my list items not adding

why are my Listbox items not added? to Listbox, I don't get it.
the code looks ok just did some modification to the new instance of GUI and now my Listbox items not adding
not sure where the error is just testing as i await your response from all you pros.
feel free to run this and test it and kindly point out the issue thanks.
gridder.buildGUI =function(thisObj){
dialog = (thisObj instanceof Panel) ? thisObj : new Window("palette", thisObj.scriptTitle, undefined, {resizeable:true});
var w = dialog;
dialog.text = "ALL IN ONE TOOLBOX 2022";
dialog.preferredSize.width = 180;
dialog.preferredSize.height = 520;
dialog.orientation = "column";
dialog.alignChildren = ["fill","top"];
dialog.spacing = 10;
dialog.margins = 16;
var tpanel = dialog.add("tabbedpanel", undefined, undefined, {name: "tpanel"});
tpanel.alignChildren = "fill";
tpanel.preferredSize.width = 348;
tpanel.margins = 0;
// CLRTAB
// ======
var Main = tpanel.add("tab", undefined, undefined, {name: "clrTab"});
Main.text = "Main";
Main.orientation = "column";
Main.alignChildren = ["fill","top"];
Main.spacing = 10;
Main.margins = 10;
// CLRTAB_LSTGRP
// =============
var clrTab_LstGrp = Main.add("group", undefined, {name: "clrTab_LstGrp"});
//clrTab_LstGrp.orientation = "row";
clrTab_LstGrp.alignChildren = ["left","center"];
clrTab_LstGrp.spacing = 10;
clrTab_LstGrp.margins = 0;
var t = Main.add("statictext", undefined, "Hello", {multiline:false});
t.text = "Create Solids";
t.graphics.foregroundColor = t.graphics.newPen (t.graphics.PenType.SOLID_COLOR, [0.0, 1.0, 1.0], 1);
t.graphics.font = ScriptUI.newFont ("Arial", "Bold", 30);
var listBoxxa = Main.add("listbox", undefined, undefined, {name: "listBoxxa", items: listBoxxa_array});
listBoxxa.preferredSize.width = 300;
listBoxxa.size = [100, 130];
var listBoxxa_array = [
"Create 2 solids",
"Create Solid",
"Create Solid with fractual noise",
"Create Solid CC Particle World",
"Create Solid Particular",
"Solid With BCC Sphere",
"Solid With BCC Turbulence",
];
if (dialog instanceof Window){
dialog.center();
dialog.show();
}
else dialog.layout.layout(true);
};
gridder.buildGUI(gridder);
When you create the Listbox you haven't yet initialised listBoxxa_array. So when you create the control object you're giving it an undefined variable as its contents. Move the section where you define listBoxxa_array above the line where you define listBoxxa.

Fabric.JS scaleToWidth not working for text items and resulting in different width then set

I try to set a defined width for a text object by below code (excerpt) but get a different width instead. e.g. "size to be 200" and "new size after render 202.25..." as differences. What am I missing or is this a bug?
var canvas = this.__canvas = new fabric.Canvas('c');
var size = 200;
var color = "#ff0000";
var fontScale = 1;
console.log("size to be "+size);
var opt = {
fill: color,
stroke: color,
scaleX: fontScale,
scaleY: fontScale,
fontFamily: "Times New Roman",
fontSize: 40,
fontWeight: "",
fontStyle: "",
textAlign: "center"
}
var itext = new fabric.Text("Hallo", opt);
canvas.add(itext);
itext.scaleToWidth(size);
canvas.renderAll();
console.log("new size after render "+itext.getScaledWidth());
Fiddle: http://jsfiddle.net/tomfree/drcqpwxy/4/

Flutter Web: Crop image without dart:io

I'm writing this at a time when dart:io is not available for Flutter Web. dart:io has the commonly used 'File' type which is required by most Flutter imaging packages.
Attempting to crop an image of unknown encoding in the UInt8List format. I spent a few days building out a simple cropping tool without dart:io
Check below for solution.
I would turn it into a package but I'm rushing through a project and don't have time.
Use This block of code to initialize the cropping route:
Future<Uint8List> cropResult = await Navigator.push(
context,
MaterialPageRoute(
builder: (ctx) => Cropper(
image: _image,
),
),
);
_image = await cropResult;
Here is the route page managing the crop. Very basic.
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as Im;
import 'dart:math';
class Cropper extends StatefulWidget {
final Uint8List image;
const Cropper({Key key, this.image}) : super(key: key);
#override
_CropperState createState() => _CropperState(image: image);
}
class _CropperState extends State<Cropper> {
Uint8List image;
Uint8List resultImg;
double scale = 1.0;
double zeroScale; //Initial scale to fit image in bounding crop box.
Offset offset = Offset(0.0, 0.0); //Used in translation of image.
double cropRatio = 6 / 10; //aspect ratio of desired crop.
Im.Image decoded; //decoded image to get pixel dimensions
double imgWidth; //img pixel width
double imgHeight; //img pixel height
Size cropArea; //Size of crop bonding box
double cropPad; //Aesthetic crop box padding.
double pXa; //Positive X available in translation
double pYa; //Positive Y available in translation
double totalX; //Total X of scaled image
double totalY; //Total Y of scaled image
Completer _decoded = Completer<bool>();
Completer _encoded = Completer<Uint8List>();
_CropperState({this.image});
#override
initState() {
_decodeImg();
super.initState();
}
_decodeImg() {
if (_decoded.isCompleted) return;
decoded = Im.decodeImage(image);
imgWidth = decoded.width.toDouble();
imgHeight = decoded.height.toDouble();
_decoded?.complete(true);
}
_encodeImage(Im.Image cropped) async {
resultImg = Im.encodePng(cropped);
_encoded?.complete(resultImg);
}
void _cropImage() async {
double xPercent = pXa != 0.0 ? 1.0 - (offset.dx + pXa) / (2 * pXa) : 0.0;
double yPercent = pYa != 0.0 ? 1.0 - (offset.dy + pYa) / (2 * pYa) : 0.0;
double cropXpx = imgWidth * cropArea.width / totalX;
double cropYpx = imgHeight * cropArea.height / totalY;
double x0 = (imgWidth - cropXpx) * xPercent;
double y0 = (imgHeight - cropYpx) * yPercent;
Im.Image cropped = Im.copyCrop(
decoded, x0.toInt(), y0.toInt(), cropXpx.toInt(), cropYpx.toInt());
_encodeImage(cropped);
Navigator.pop(context, _encoded.future);
}
computeRelativeDim(double newScale) {
totalX = newScale * cropArea.height * imgWidth / imgHeight;
totalY = newScale * cropArea.height;
pXa = 0.5 * (totalX - cropArea.width);
pYa = 0.5 * (totalY - cropArea.height);
}
bool init = true;
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Crop Photo'),
centerTitle: true,
leading: IconButton(
onPressed: _cropImage,
tooltip: 'Crop',
icon: Icon(Icons.crop),
),
actions: [
RaisedButton(
onPressed: () => Navigator.pop(context, null),
child: Text('Cancel'),
)
],
),
body: Column(
children: <Widget>[
Expanded(
child: FutureBuilder(
future: _decoded.future,
builder: (ctx, snap) {
if (!snap.hasData)
return Center(
child: Text('Loading...'),
);
return LayoutBuilder(
builder: (ctx, cstr) {
if (init) {
cropPad = cstr.maxHeight * 0.05;
double tmpWidth = cstr.maxWidth - 2 * cropPad;
double tmpHeight = cstr.maxHeight - 2 * cropPad;
cropArea = (tmpWidth / cropRatio > tmpHeight)
? Size(tmpHeight * cropRatio, tmpHeight)
: Size(tmpWidth, tmpWidth / cropRatio);
zeroScale = cropArea.height / imgHeight;
computeRelativeDim(scale);
init = false;
}
return GestureDetector(
onPanUpdate: (pan) {
double dy;
double dx;
if (pan.delta.dy > 0)
dy = min(pan.delta.dy, pYa - offset.dy);
else
dy = max(pan.delta.dy, -pYa - offset.dy);
if (pan.delta.dx > 0)
dx = min(pan.delta.dx, pXa - offset.dx);
else
dx = max(pan.delta.dx, -pXa - offset.dx);
setState(() => offset += Offset(dx, dy));
},
child: Stack(
children: [
Container(
color: Colors.black.withOpacity(0.5),
height: cstr.maxHeight,
width: cstr.maxWidth,
child: ClipRect(
child: Container(
alignment: Alignment.center,
height: cropArea.height,
width: cropArea.width,
child: Transform.translate(
offset: offset,
child: Transform.scale(
scale: scale * zeroScale,
child: OverflowBox(
maxWidth: imgWidth,
maxHeight: imgHeight,
child: Image.memory(
image,
),
),
),
),
),
),
),
IgnorePointer(
child: Center(
child: Container(
height: cropArea.height,
width: cropArea.width,
decoration: BoxDecoration(
border:
Border.all(color: Colors.white, width: 2),
),
),
),
),
],
),
);
},
);
},
),
),
Row(
children: <Widget>[
Text('Scale:'),
Expanded(
child: SliderTheme(
data: theme.sliderTheme,
child: Slider(
divisions: 50,
value: scale,
min: 1,
max: 2,
label: '$scale',
onChanged: (n) {
double dy;
double dx;
computeRelativeDim(n);
dy = (offset.dy > 0)
? min(offset.dy, pYa)
: max(offset.dy, -pYa);
dx = (offset.dx > 0)
? min(offset.dx, pXa)
: max(offset.dx, -pXa);
setState(() {
offset = Offset(dx, dy);
scale = n;
});
},
),
),
),
],
),
],
),
);
}
}

Fabricjs mask object with transformation

I'm trying to mask an object using Fabric.js free drawing brush. It works fine if the object is in its default position and without any transformations. But once I add transformations to the object, the mask is placed in the wrong position. I'm not sure how to solve this. Can someone take a look?
I want to be able to apply any transformations, before or after the mask, without messing up the mask.
let canvas = new fabric.Canvas("canvas", {
backgroundColor: "lightgray",
width: 1280,
height: 720,
preserveObjectStacking: true,
selection: false,
stateful: true
});
canvas.isDrawingMode = true;
canvas.freeDrawingBrush.color = "black";
canvas.freeDrawingBrush.width = 2;
canvas.on("path:created", function(options) {
clip(options.path);
});
function clip(path) {
canvas.isDrawingMode = false;
canvas.remove(path);
let mask = new fabric.Path(path.path, {
top: object.top,
left: object.left,
objectCaching: false,
strokeWidth: 0,
pathOffset: {
x: 0,
y: 0
}
});
let originalObjLeft = object.left,
originalObjTop = object.top;
object.set({
clipTo: function(ctx) {
mask.set({
left: -object.width / 2 - mask.width / 2 - originalObjLeft,
top: -object.height / 2 - mask.height / 2 - originalObjTop,
objectCaching: false
});
mask.render(ctx);
}
});
canvas.requestRenderAll();
}
// image
let image = new Image();
let object;
image.onload = function() {
object = new fabric.Image(image, {
width: 500,
height: 500,
//scaleX: 0.8,
//scaleY: 0.8,
//angle: 45,
top: 50,
left: 300
});
canvas.add(object);
};
image.src = "http://i.imgur.com/8rmMZI3.jpg";
I implement an exemple with some transformations (scaleX,scaleY,left,top).
I'm strugle to find a solution when the inital object have an angle different than 0. For the current solution I need it to divide the maskscale with the object scale and also adjust the positions.
let canvas = new fabric.Canvas("canvas", {
backgroundColor: "lightgray",
width: 1280,
height: 720,
preserveObjectStacking: true,
selection: false,
stateful: true
});
canvas.isDrawingMode = true;
canvas.freeDrawingBrush.color = "black";
canvas.freeDrawingBrush.width = 2;
canvas.on("path:created", function(options) {
clip(options.path);
});
function clip(path) {
canvas.isDrawingMode = false;
canvas.remove(path);
let mask = new fabric.Path(path.path, {
top: object.top,
left: object.left,
objectCaching: false,
strokeWidth: 0,
scaleX : 1/object.scaleX,
scaleY : 1/object.scaleY,
pathOffset: {
x: 0,
y: 0
}
});
let originalObjLeft = object.left,
originalObjTop = object.top,
originalMaskScaleX = mask.scaleX,
originalMaskScaleY = mask.scaleY,
originalObjScaleX = object.scaleX,
originalObjScaleY = object.scaleY;
object.set({
clipTo: function(ctx) {
mask.set({
left: -object.width / 2 -( mask.width / 2 * originalMaskScaleX) - originalObjLeft/originalObjScaleX ,
top: -object.height / 2 -( mask.height / 2 * originalMaskScaleY) - originalObjTop/originalObjScaleY ,
objectCaching: false
});
mask.render(ctx);
}
});
canvas.requestRenderAll();
}
// image
let image = new Image();
image.onload = function() {
object = new fabric.Image(image, {
width: 500,
height: 500,
scaleX: 0.8,
scaleY: 0.8,
// angle: 45,
top: 50,
left: 100
});
canvas.add(object);
};
image.src = "http://i.imgur.com/8rmMZI3.jpg";
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.6/fabric.js"></script>
<div class="canvas__wrapper">
<canvas id="canvas" width="1280" height="720"></canvas>
</div>
You can check here for loadFromJSON support.
The only problem remains is when the object is rotated.
Basically whenever you set an angle, your context matrix has been transformed. In order to mask properly you need to return to initial state of the Transformation Matrices. Fabricjs handles first matrix with center point of an object (calculates center of an object with or without an angle). Second matrix is rotating matrix, and third - scaling.
To display image with all options which are set to an object, you need to multiply all Matrices:
(First Matrix * Second Matrix) * Third Matrix
So the idea of clipping will be reverse engineering of rotating context and multiplications of matrices:
difference between center points of regular object without rotation and center point of the same object but with rotation. After that take result of subtractions and divide by original object scale value.
let canvas = new fabric.Canvas("canvas", {
backgroundColor: "lightgray",
width: 1280,
height: 720,
preserveObjectStacking: true,
selection: false,
stateful: true
});
const angle = 45;
let objectHasBeenRotated = false;
canvas.isDrawingMode = true;
canvas.freeDrawingBrush.color = "black";
canvas.freeDrawingBrush.width = 2;
canvas.on("path:created", function (options) {
clip(options.path);
});
function clip(path) {
canvas.isDrawingMode = false;
canvas.remove(path);
let mask = new fabric.Path(path.path, {
top: 0,
left: 0,
objectCaching: false,
strokeWidth: 0,
scaleX: 1 / object.scaleX,
scaleY: 1 / object.scaleY,
pathOffset: {
x: 0,
y: 0,
}
});
let originalObjLeft = object.left,
originalObjTop = object.top,
originalMaskScaleX = mask.scaleX,
originalMaskScaleY = mask.scaleY,
originalObjScaleX = object.scaleX,
originalObjScaleY = object.scaleY,
transformedTranslate = object.translateToGivenOrigin({
x: object.left,
y: object.top
}, object.originX, object.originY, 'center', 'center'),
originalTransformLeft = transformedTranslate.x - object.getCenterPoint().x,
originalTransformTop = transformedTranslate.y - object.getCenterPoint().y;
object.set({
clipTo: function (ctx) {
ctx.save();
ctx.rotate(-angle * Math.PI / 180);
ctx.translate(originalTransformLeft / originalObjScaleX, originalTransformTop / originalObjScaleY)
mask.set({
left: -object.width / 2 - (mask.width / 2 * originalMaskScaleX) - originalObjLeft / originalObjScaleX,
top: -object.height / 2 - (mask.height / 2 * originalMaskScaleY) - originalObjTop / originalObjScaleY,
objectCaching: false
});
mask.render(ctx);
ctx.restore();
}
});
canvas.requestRenderAll();
}
// image
let image = new Image();
image.onload = function () {
object = new fabric.Image(image, {
width: 500,
height: 500,
scaleX: 0.8,
scaleY: 0.8,
angle: angle,
top: 50,
left: 300,
id: 'pug'
});
canvas.add(object);
};
image.src = "http://i.imgur.com/8rmMZI3.jpg";
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.6/fabric.js"></script>
<div class="canvas__wrapper">
<canvas id="canvas" width="1280" height="720"></canvas>
</div>

fabricjs how i can make an angle measurement?

i want to use fabricjs for create an Object and can measure some images sections .
Update:
I follow sample of http://fabricjs.com/stickman/ and seems I have something but need to improve more
here is what i have https://jsfiddle.net/mavirroco/gtfw58st/
(function () {
var canvas = this.__canvas = new fabric.Canvas('c', {
selection: false
});
var text1 = new fabric.Text('0 Deg', {
fontSize: 20,
fontFamily: 'Georgia',
top: 10,
left: 100
});
canvas.add(text1);
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
function makeCircle(left, top, line1, line2, line3, line4) {
var c = new fabric.Triangle({
left: left,
top: top,
strokeWidth: 5,
fill: '#fff',
stroke: '#666',
angle: -180,
width: 10,
height: 10
});
c.hasControls = c.hasBorders = false;
c.line1 = line1;
c.line2 = line2;
c.line3 = line3;
c.line4 = line4;
return c;
}
function makeLine(coords) {
return new fabric.Line(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 5,
selectable: false
});
}
var line2 = makeLine([250, 175, 250, 250]),
line3 = makeLine([250, 250, 300, 350]),
line4 = makeLine([250, 250, 200, 350]);
canvas.add(line3, line4);
canvas.add(
makeCircle(line2.get('x2'), line2.get('y2'), line2, line3, line4),
makeCircle(line3.get('x2'), line3.get('y2'), line3),
makeCircle(line4.get('x2'), line4.get('y2'), line4));
canvas.on('object:moving', function (e) {
var p = e.target;
p.line1 && p.line1.set({
'x2': p.left,
'y2': p.top
});
p.line2 && p.line2.set({
'x1': p.left,
'y1': p.top
});
p.line3 && p.line3.set({
'x1': p.left,
'y1': p.top
});
p.line4 && p.line4.set({
'x1': p.left,
'y1': p.top
});
canvas.renderAll();
dy = line3.get('y2') - line4.get('y2');
dx = line3.get('x2') - line4.get('x2');
theta = Math.atan2(dy, dx);
theta *= 180 / Math.PI // rads to degs
text1.setText(parseFloat(theta).toFixed(2));
});
})();
y11 = line3.get('y1');
y12 = line3.get('y2');
y21 = line4.get('y1');
y22 = line4.get('y2');
x11 = line3.get('x1');
x12 = line3.get('x2');
x21 = line4.get('x1');
x22 = line4.get('x2');
angle1 = Math.atan2(y11 - y12, x11 - x12);
angle2 = Math.atan2(y21 - y22, x21 - x22);
angle = angle1 - angle2;
angle = angle*180/Math.PI;
if(angle < 0) angle = -angle;
if(360 - angle < angle) angle = 360 - angle;
text1.setText(angle.toString());
https://jsfiddle.net/gtfw58st/5/

Resources