Skip to content

Commit

Permalink
Merge pull request #6 from dkyowell/0.2.2
Browse files Browse the repository at this point in the history
0.2.2
  • Loading branch information
dkyowell authored Apr 17, 2024
2 parents 1ee0bf7 + 38930e6 commit 40a21ed
Show file tree
Hide file tree
Showing 23 changed files with 495 additions and 153 deletions.
7 changes: 7 additions & 0 deletions Documentation/Design.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,10 @@ Elliptical Gradient: Easy

* Text Gradient Fill: I had this working with a couple of caveats. Multiline text would not render. This seems to be a
limitation of CoreGraphics.



# SO, INSTEAD OF THAT...

Run a page...when a

70 changes: 70 additions & 0 deletions Documentation/ToDo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# To Do List

## Version 1.0 Roadmap
### PageWrap Text

### Column Layout

### Offset

### Rotation

### VGrid

## Partialy Implmented
### Grids
There should be more layout options.

### Shape
There are many intersection, union, etc functions that I have not yet implemented. Path is just a very thin layer
on top of MutablePath. I could just get rid of all of it and operate directly upon a MutablePath. Or, I could
expose MutablePath.

## Fixes

### Overlays
Need to review overlay rendering deferal. It seems that overlays are not being rendered in many cases.



## Reevaluate

### Default Positioning
TopLeading or Center?


### Expose Renderable
Is there a way to make a CustomBlock that uses .sizeFor(), but that does not expose the full Renderable protocol?
Exposing Renderer would not be a big deal.
Offer a PDFBlocksAdvanced import with Renderable?

### Layout


## Version > 1.0
### Leading to Trailing Page Wrap
Currently page wrap only works with elements that flow from top to bottom.

### Gradient fill for text
I have attempted this, but ran into a couple of dead ends. 1) When the Text was in a stack with other elements, the
gradient would randomly decide to spill over the entire page. 2) The gradient would not work at all with multi line
text.

### Text along a path




## Version 2.0
If library gains widespready adoption, the following could be considered for a 2.0 release.

### Secondary Page Wrap Blocks
Allow Borders, Backgrounds, Overlays, etc

### Custom Layouts
This will wait for a use case and more widespready adoption of PDFBlocks. Any users who are held up would be able
to fork and implement their own.

### Text around a path
This would require CoreText,

7 changes: 7 additions & 0 deletions Sources/PDFBlocks/API/Core/Shape.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@ import Foundation
/// foreground color.
public protocol Shape: Block {
func path(in rect: CGRect) -> Path
func sizeThatFits(_ proposal: CGSize) -> CGSize
}

public extension Shape {
var body: some Block {
RenderableShape(shape: self)
}
}

public extension Shape {
func sizeThatFits(_ proposal: CGSize) -> CGSize {
proposal
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@

import Foundation

// extension Gradient: ShapeStyle {}
extension Block {
func offset(x: Size, y: Size) -> some Block {
modifier(OffsetModifier(x: x, y: y))
}
}
13 changes: 1 addition & 12 deletions Sources/PDFBlocks/API/Modifiers/Block+Opacity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,6 @@ public extension Block {
/// - Parameter opacity: The opacity value to apply.
/// - Returns: A block for which the given opacity has been set.
func opacity(_ opacity: CGFloat) -> some Block {
environment(\.opacity, opacity)
}
}

struct OpacityKey: EnvironmentKey {
static let defaultValue: CGFloat = 1
}

extension EnvironmentValues {
var opacity: CGFloat {
get { self[OpacityKey.self] }
set { self[OpacityKey.self] = self[OpacityKey.self] * newValue }
modifier(OpacityModifier(opacity: opacity))
}
}
13 changes: 13 additions & 0 deletions Sources/PDFBlocks/API/Modifiers/Block+RotationEffect.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* PDF Blocks
* Copyright (c) David Yowell 2024
* MIT license, see LICENSE file for details
*/

import Foundation

extension Block {
func rotationEffect(_ angle: Angle, anchor: UnitPoint = .center) -> some Block {
modifier(RotationModifier(angle: angle, anchor: anchor))
}
}
5 changes: 5 additions & 0 deletions Sources/PDFBlocks/API/Shapes/Circle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,9 @@ public struct Circle: Shape {
let origin = CGPoint(x: (rect.width - length) / 2, y: (rect.height - length) / 2)
return Path(ellipseIn: CGRect(origin: origin, size: size))
}

public func sizeThatFits(_ proposal: CGSize) -> CGSize {
let minLength = min(proposal.width, proposal.height)
return .init(width: minLength, height: minLength)
}
}
5 changes: 5 additions & 0 deletions Sources/PDFBlocks/API/Shapes/Square.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,9 @@ public struct Square: Shape {
let origin = CGPoint(x: (rect.width - length) / 2, y: (rect.height - length) / 2)
return Path(CGRect(origin: origin, size: size))
}

public func sizeThatFits(_ proposal: CGSize) -> CGSize {
let minLength = min(proposal.width, proposal.height)
return .init(width: minLength, height: minLength)
}
}
22 changes: 12 additions & 10 deletions Sources/PDFBlocks/Examples/Example+HGrid.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,16 @@ private struct Document: Block {
Page(size: .init(width: .in(6), height: .in(6)), margins: .in(1)) {
PageNumberReader { pageNo in
Text("Page \(pageNo)")
.padding(.bottom, .pt(CGFloat(pageNo * 12)))
}
.font(size: 36)
.padding(.horizontal, .max)
.padding(.bottom, .pt(12))
// .padding(.bottom, .pt(12))
VStack(alignment: .center, allowPageWrap: true) {
Text("A")
Text("B")
Text("C")
HGrid(columnCount: 3, columnSpacing: .in(0), rowSpacing: .pt(4), allowPageWrap: true) {
Text("A")
Text("B")
Text("C")
HGrid(columnCount: 3, columnSpacing: .pt(0), rowSpacing: .pt(0), allowPageWrap: true) {
Text("D")
Text("E")
Text("F")
Expand All @@ -76,22 +74,26 @@ private struct Document: Block {
Text("U")
Text("V")
Text("W")
Text("X")
Text("Y")
Text("Z")
}
.border(Color.orange, width: .in(2))
.font(size: 12)
Text("X")
Text("Y")
Text("Z")
}
.padding(.horizontal, .max)
.overlay {
Color.clear
.border(.blue, width: .pt(12))
.opacity(0.75)
}
.font(size: 24)
.padding(.pt(12))
.rotationEffect(.degrees(10))
Text("Footer")
}
.background {
Color.orange
}
.offset(x: .pt(-36), y: .pt(36))
.border(Color.black, width: .pt(12))
.font(name: "American Typewriter")
}
Expand Down
104 changes: 92 additions & 12 deletions Sources/PDFBlocks/Examples/Example+Shapes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,94 @@ private struct Document: Block {
endPoint: .trailing)
let radialGradient = RadialGradient(colors: [.red, .orange, .yellow],
center: .center,
startRadius: .in(0),
endRadius: .in(5))
startRadius: .in(3),
endRadius: .in(8))
var body: some Block {
Page(size: .letter, margins: .in(1)) {
Text("Stroked Text")
.padding(.horizontal, .max)
.font(size: 72)
.bold()
.textStroke(color: .red, lineWidth: .pt(2))
Arc(startAngle: .degrees(30), endAngle: .degrees(330), clockwise: false)
.fill(radialGradient)
.padding(.max)
.stroke(linearGradient, lineWidth: .pt(24))
Rectangle()
.fill(.yellow)
.aspectRatio(1)
// .stroke(.black, lineWidth: .pt(4))
.border(Color.black)
.rotationEffect(.degrees(45))
.padding(.pt(100))
}
}

// var body: some Block {
// Page(size: .letter, margins: .in(1)) {
// VStack(spacing: .pt(16)) {
// VStack(alignment: .center) {
// Text("Wonka Wonka")
// Arc(startAngle: .degrees(35), endAngle: .degrees(325), clockwise: false)
// .fill(.yellow)
// .stroke(.black, lineWidth: .pt(4))
// .padding(.max)
// }
// VStack(alignment: .center) {
// Text("Wonka Wonka")
// Arc(startAngle: .degrees(35), endAngle: .degrees(325), clockwise: false)
// .fill(.yellow)
// .stroke(.black, lineWidth: .pt(4))
// .padding(.max)
// }
// .rotationEffect(.degrees(90), unitPoint: .leading)
// VStack(alignment: .center) {
// Text("Wonka Wonka")
// Arc(startAngle: .degrees(35), endAngle: .degrees(325), clockwise: false)
// .fill(.yellow)
// .stroke(.black, lineWidth: .pt(4))
// .padding(.max)
// }
// .rotationEffect(.degrees(180))
// VStack(alignment: .center) {
// Text("Wonka Wonka")
// Arc(startAngle: .degrees(35), endAngle: .degrees(325), clockwise: false)
// .fill(.yellow)
// .stroke(.black, lineWidth: .pt(4))
// .padding(.max)
// }
// .rotationEffect(.degrees(270))
// }
// }
// }
}

// TODO: ANOTHER EXAMPLE OF DEFERRED BORDERS NOT RENDERING PROPERLY
// var body: some Block {
// Page(size: .letter, margins: .in(1)) {
// Rectangle()
// .fill(.yellow)
// .aspectRatio(1)
// //.stroke(.black, lineWidth: .pt(4))
// .border(Color.black)
// .rotationEffect(.degrees(45))
// .padding(.pt(100))
// }
// }

private struct DoesNotRenderSecondOverlay: Block {
let linearGradient = LinearGradient(colors: [.cyan, .purple, .blue],
startPoint: .leading,
endPoint: .trailing)
let radialGradient = RadialGradient(colors: [.red, .orange, .yellow],
center: .center,
startRadius: .in(3),
endRadius: .in(8))
var body: some Block {
Page(size: .letter, margins: .in(1)) {
Square()
.fill(.clear)
.overlay {
Arc(startAngle: .degrees(35), endAngle: .degrees(325), clockwise: false)
.fill(.yellow)
.overlay {
Circle()
.fill(.black)
.opacity(0.25)
}
.border(.black)
}
}
}
}
Expand All @@ -39,9 +114,14 @@ struct Arc: Shape {
let radius = min(rect.width, rect.height) / 2
path.addLines([CGPoint(x: rect.midX, y: rect.midY)])
path.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: clockwise)
path.addLine(to: CGPoint(x: rect.midX, y: rect.midY))
path.closeSubpath()
}
}

public func sizeThatFits(_ proposal: CGSize) -> CGSize {
let minLength = min(proposal.width, proposal.height)
return .init(width: minLength, height: minLength)
}
}

struct StarShape: Shape {
Expand Down
6 changes: 2 additions & 4 deletions Sources/PDFBlocks/Internal/Blocks/Border.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ extension Border: Renderable {
func render(context: Context, environment: EnvironmentValues, rect: CGRect) {
content.getRenderable(environment: environment)
.render(context: context, environment: environment, rect: rect)
context.renderPass3.append {
context.renderer.renderBorder(environment: environment, rect: rect, shapeStyle: shapeStyle,
width: width.points)
}
context.renderer.renderBorder(environment: environment, rect: rect, shapeStyle: shapeStyle,
width: width.points)
}

func getTrait<Value>(context: Context, environment: EnvironmentValues, keypath: KeyPath<Trait, Value>) -> Value {
Expand Down
7 changes: 4 additions & 3 deletions Sources/PDFBlocks/Internal/Blocks/HGrid+Renderable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ extension HGrid: Renderable {
wrappingModeRender(context: context, environment: environment, rect: rect)
} else {
// This is a primary page wrapping block
guard context.renderPass2 == nil else {
context.renderer.setLayer(2)
context.setPageWrapRect(rect)
guard context.multiPagePass == nil else {
return
}
context.renderPass2 = {
context.setPageWrapRect(rect)
context.multiPagePass = {
environment.renderMode = .wrapping
wrappingModeRender(context: context, environment: environment, rect: rect)
}
Expand Down
Loading

0 comments on commit 40a21ed

Please sign in to comment.