Completed
Pull Request — master (#6457)
by Julius
22:46
created
apps/theming/lib/IconBuilder.php 1 patch
Indentation   +177 added lines, -177 removed lines patch added patch discarded remove patch
@@ -29,182 +29,182 @@
 block discarded – undo
29 29
 use OCP\Files\SimpleFS\ISimpleFile;
30 30
 
31 31
 class IconBuilder {
32
-	/** @var ThemingDefaults */
33
-	private $themingDefaults;
34
-	/** @var Util */
35
-	private $util;
36
-
37
-	/**
38
-	 * IconBuilder constructor.
39
-	 *
40
-	 * @param ThemingDefaults $themingDefaults
41
-	 * @param Util $util
42
-	 */
43
-	public function __construct(
44
-		ThemingDefaults $themingDefaults,
45
-		Util $util
46
-	) {
47
-		$this->themingDefaults = $themingDefaults;
48
-		$this->util = $util;
49
-	}
50
-
51
-	/**
52
-	 * @param $app string app name
53
-	 * @return string|false image blob
54
-	 */
55
-	public function getFavicon($app) {
56
-		try {
57
-			$icon = $this->renderAppIcon($app, 32);
58
-			if ($icon === false) {
59
-				return false;
60
-			}
61
-			$icon->setImageFormat("png32");
62
-			$data = $icon->getImageBlob();
63
-			$icon->destroy();
64
-			return $data;
65
-		} catch (\ImagickException $e) {
66
-			return false;
67
-		}
68
-	}
69
-
70
-	/**
71
-	 * @param $app string app name
72
-	 * @return string|false image blob
73
-	 */
74
-	public function getTouchIcon($app) {
75
-		try {
76
-			$icon = $this->renderAppIcon($app, 512);
77
-			if ($icon === false) {
78
-				return false;
79
-			}
80
-			$icon->setImageFormat("png32");
81
-			$data = $icon->getImageBlob();
82
-			$icon->destroy();
83
-			return $data;
84
-		} catch (\ImagickException $e) {
85
-			return false;
86
-		}
87
-	}
88
-
89
-	/**
90
-	 * Render app icon on themed background color
91
-	 * fallback to logo
92
-	 *
93
-	 * @param $app string app name
94
-	 * @param $size int size of the icon in px
95
-	 * @return Imagick|false
96
-	 */
97
-	public function renderAppIcon($app, $size) {
98
-		$appIcon = $this->util->getAppIcon($app);
99
-		if($appIcon === false) {
100
-			return false;
101
-		}
102
-		if ($appIcon instanceof ISimpleFile) {
103
-			$appIconContent = $appIcon->getContent();
104
-			$mime = $appIcon->getMimeType();
105
-		} else {
106
-			$appIconContent = file_get_contents($appIcon);
107
-			$mime = mime_content_type($appIcon);
108
-		}
109
-
110
-		if($appIconContent === false || $appIconContent === "") {
111
-			return false;
112
-		}
113
-
114
-		$color = $this->themingDefaults->getColorPrimary();
115
-
116
-		// generate background image with rounded corners
117
-		$background = '<?xml version="1.0" encoding="UTF-8"?>' .
118
-			'<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:cc="http://creativecommons.org/ns#" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink">' .
119
-			'<rect x="0" y="0" rx="100" ry="100" width="512" height="512" style="fill:' . $color . ';" />' .
120
-			'</svg>';
121
-		// resize svg magic as this seems broken in Imagemagick
122
-		if($mime === "image/svg+xml" || substr($appIconContent, 0, 4) === "<svg") {
123
-			if(substr($appIconContent, 0, 5) !== "<?xml") {
124
-				$svg = "<?xml version=\"1.0\"?>".$appIconContent;
125
-			} else {
126
-				$svg = $appIconContent;
127
-			}
128
-			$tmp = new Imagick();
129
-			$tmp->readImageBlob($svg);
130
-			$x = $tmp->getImageWidth();
131
-			$y = $tmp->getImageHeight();
132
-			$res = $tmp->getImageResolution();
133
-			$tmp->destroy();
134
-
135
-			if($x>$y) {
136
-				$max = $x;
137
-			} else {
138
-				$max = $y;
139
-			}
140
-
141
-			// convert svg to resized image
142
-			$appIconFile = new Imagick();
143
-			$resX = (int)(512 * $res['x'] / $max * 2.53);
144
-			$resY = (int)(512 * $res['y'] / $max * 2.53);
145
-			$appIconFile->setResolution($resX, $resY);
146
-			$appIconFile->setBackgroundColor(new ImagickPixel('transparent'));
147
-			$appIconFile->readImageBlob($svg);
148
-
149
-			/**
150
-			 * invert app icons for bright primary colors
151
-			 * the default nextcloud logo will not be inverted to black
152
-			 */
153
-			if ($this->util->invertTextColor($color)
154
-				&& !$appIcon instanceof ISimpleFile
155
-				&& $app !== "core"
156
-			) {
157
-				$appIconFile->negateImage(false);
158
-			}
159
-			$appIconFile->scaleImage(512, 512, true);
160
-		} else {
161
-			$appIconFile = new Imagick();
162
-			$appIconFile->setBackgroundColor(new ImagickPixel('transparent'));
163
-			$appIconFile->readImageBlob($appIconContent);
164
-			$appIconFile->scaleImage(512, 512, true);
165
-		}
166
-		// offset for icon positioning
167
-		$border_w = (int)($appIconFile->getImageWidth() * 0.05);
168
-		$border_h = (int)($appIconFile->getImageHeight() * 0.05);
169
-		$innerWidth = (int)($appIconFile->getImageWidth() - $border_w * 2);
170
-		$innerHeight = (int)($appIconFile->getImageHeight() - $border_h * 2);
171
-		$appIconFile->adaptiveResizeImage($innerWidth, $innerHeight);
172
-		// center icon
173
-		$offset_w = 512 / 2 - $innerWidth / 2;
174
-		$offset_h = 512 / 2 - $innerHeight / 2;
175
-
176
-		$finalIconFile = new Imagick();
177
-		$finalIconFile->setBackgroundColor(new ImagickPixel('transparent'));
178
-		$finalIconFile->readImageBlob($background);
179
-		$finalIconFile->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
180
-		$finalIconFile->setImageArtifact('compose:args', "1,0,-0.5,0.5");
181
-		$finalIconFile->compositeImage($appIconFile, Imagick::COMPOSITE_ATOP, $offset_w, $offset_h);
182
-		$finalIconFile->setImageFormat('png24');
183
-		if (defined("Imagick::INTERPOLATE_BICUBIC") === true) {
184
-			$filter = Imagick::INTERPOLATE_BICUBIC;
185
-		} else {
186
-			$filter = Imagick::FILTER_LANCZOS;
187
-		}
188
-		$finalIconFile->resizeImage($size, $size, $filter, 1, false);
189
-
190
-		$appIconFile->destroy();
191
-		return $finalIconFile;
192
-	}
193
-
194
-	public function colorSvg($app, $image) {
195
-		try {
196
-			$imageFile = $this->util->getAppImage($app, $image);
197
-		} catch (AppPathNotFoundException $e) {
198
-			return false;
199
-		}
200
-		$svg = file_get_contents($imageFile);
201
-		if ($svg !== false && $svg !== "") {
202
-			$color = $this->util->elementColor($this->themingDefaults->getColorPrimary());
203
-			$svg = $this->util->colorizeSvg($svg, $color);
204
-			return $svg;
205
-		} else {
206
-			return false;
207
-		}
208
-	}
32
+    /** @var ThemingDefaults */
33
+    private $themingDefaults;
34
+    /** @var Util */
35
+    private $util;
36
+
37
+    /**
38
+     * IconBuilder constructor.
39
+     *
40
+     * @param ThemingDefaults $themingDefaults
41
+     * @param Util $util
42
+     */
43
+    public function __construct(
44
+        ThemingDefaults $themingDefaults,
45
+        Util $util
46
+    ) {
47
+        $this->themingDefaults = $themingDefaults;
48
+        $this->util = $util;
49
+    }
50
+
51
+    /**
52
+     * @param $app string app name
53
+     * @return string|false image blob
54
+     */
55
+    public function getFavicon($app) {
56
+        try {
57
+            $icon = $this->renderAppIcon($app, 32);
58
+            if ($icon === false) {
59
+                return false;
60
+            }
61
+            $icon->setImageFormat("png32");
62
+            $data = $icon->getImageBlob();
63
+            $icon->destroy();
64
+            return $data;
65
+        } catch (\ImagickException $e) {
66
+            return false;
67
+        }
68
+    }
69
+
70
+    /**
71
+     * @param $app string app name
72
+     * @return string|false image blob
73
+     */
74
+    public function getTouchIcon($app) {
75
+        try {
76
+            $icon = $this->renderAppIcon($app, 512);
77
+            if ($icon === false) {
78
+                return false;
79
+            }
80
+            $icon->setImageFormat("png32");
81
+            $data = $icon->getImageBlob();
82
+            $icon->destroy();
83
+            return $data;
84
+        } catch (\ImagickException $e) {
85
+            return false;
86
+        }
87
+    }
88
+
89
+    /**
90
+     * Render app icon on themed background color
91
+     * fallback to logo
92
+     *
93
+     * @param $app string app name
94
+     * @param $size int size of the icon in px
95
+     * @return Imagick|false
96
+     */
97
+    public function renderAppIcon($app, $size) {
98
+        $appIcon = $this->util->getAppIcon($app);
99
+        if($appIcon === false) {
100
+            return false;
101
+        }
102
+        if ($appIcon instanceof ISimpleFile) {
103
+            $appIconContent = $appIcon->getContent();
104
+            $mime = $appIcon->getMimeType();
105
+        } else {
106
+            $appIconContent = file_get_contents($appIcon);
107
+            $mime = mime_content_type($appIcon);
108
+        }
109
+
110
+        if($appIconContent === false || $appIconContent === "") {
111
+            return false;
112
+        }
113
+
114
+        $color = $this->themingDefaults->getColorPrimary();
115
+
116
+        // generate background image with rounded corners
117
+        $background = '<?xml version="1.0" encoding="UTF-8"?>' .
118
+            '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:cc="http://creativecommons.org/ns#" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink">' .
119
+            '<rect x="0" y="0" rx="100" ry="100" width="512" height="512" style="fill:' . $color . ';" />' .
120
+            '</svg>';
121
+        // resize svg magic as this seems broken in Imagemagick
122
+        if($mime === "image/svg+xml" || substr($appIconContent, 0, 4) === "<svg") {
123
+            if(substr($appIconContent, 0, 5) !== "<?xml") {
124
+                $svg = "<?xml version=\"1.0\"?>".$appIconContent;
125
+            } else {
126
+                $svg = $appIconContent;
127
+            }
128
+            $tmp = new Imagick();
129
+            $tmp->readImageBlob($svg);
130
+            $x = $tmp->getImageWidth();
131
+            $y = $tmp->getImageHeight();
132
+            $res = $tmp->getImageResolution();
133
+            $tmp->destroy();
134
+
135
+            if($x>$y) {
136
+                $max = $x;
137
+            } else {
138
+                $max = $y;
139
+            }
140
+
141
+            // convert svg to resized image
142
+            $appIconFile = new Imagick();
143
+            $resX = (int)(512 * $res['x'] / $max * 2.53);
144
+            $resY = (int)(512 * $res['y'] / $max * 2.53);
145
+            $appIconFile->setResolution($resX, $resY);
146
+            $appIconFile->setBackgroundColor(new ImagickPixel('transparent'));
147
+            $appIconFile->readImageBlob($svg);
148
+
149
+            /**
150
+             * invert app icons for bright primary colors
151
+             * the default nextcloud logo will not be inverted to black
152
+             */
153
+            if ($this->util->invertTextColor($color)
154
+                && !$appIcon instanceof ISimpleFile
155
+                && $app !== "core"
156
+            ) {
157
+                $appIconFile->negateImage(false);
158
+            }
159
+            $appIconFile->scaleImage(512, 512, true);
160
+        } else {
161
+            $appIconFile = new Imagick();
162
+            $appIconFile->setBackgroundColor(new ImagickPixel('transparent'));
163
+            $appIconFile->readImageBlob($appIconContent);
164
+            $appIconFile->scaleImage(512, 512, true);
165
+        }
166
+        // offset for icon positioning
167
+        $border_w = (int)($appIconFile->getImageWidth() * 0.05);
168
+        $border_h = (int)($appIconFile->getImageHeight() * 0.05);
169
+        $innerWidth = (int)($appIconFile->getImageWidth() - $border_w * 2);
170
+        $innerHeight = (int)($appIconFile->getImageHeight() - $border_h * 2);
171
+        $appIconFile->adaptiveResizeImage($innerWidth, $innerHeight);
172
+        // center icon
173
+        $offset_w = 512 / 2 - $innerWidth / 2;
174
+        $offset_h = 512 / 2 - $innerHeight / 2;
175
+
176
+        $finalIconFile = new Imagick();
177
+        $finalIconFile->setBackgroundColor(new ImagickPixel('transparent'));
178
+        $finalIconFile->readImageBlob($background);
179
+        $finalIconFile->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
180
+        $finalIconFile->setImageArtifact('compose:args', "1,0,-0.5,0.5");
181
+        $finalIconFile->compositeImage($appIconFile, Imagick::COMPOSITE_ATOP, $offset_w, $offset_h);
182
+        $finalIconFile->setImageFormat('png24');
183
+        if (defined("Imagick::INTERPOLATE_BICUBIC") === true) {
184
+            $filter = Imagick::INTERPOLATE_BICUBIC;
185
+        } else {
186
+            $filter = Imagick::FILTER_LANCZOS;
187
+        }
188
+        $finalIconFile->resizeImage($size, $size, $filter, 1, false);
189
+
190
+        $appIconFile->destroy();
191
+        return $finalIconFile;
192
+    }
193
+
194
+    public function colorSvg($app, $image) {
195
+        try {
196
+            $imageFile = $this->util->getAppImage($app, $image);
197
+        } catch (AppPathNotFoundException $e) {
198
+            return false;
199
+        }
200
+        $svg = file_get_contents($imageFile);
201
+        if ($svg !== false && $svg !== "") {
202
+            $color = $this->util->elementColor($this->themingDefaults->getColorPrimary());
203
+            $svg = $this->util->colorizeSvg($svg, $color);
204
+            return $svg;
205
+        } else {
206
+            return false;
207
+        }
208
+    }
209 209
 
210 210
 }
Please login to merge, or discard this patch.