fix: display chinese character avatar

Signed-off-by: Phreeman33 <12772373+Phreeman33@users.noreply.github.com>
pull/51855/head
Phreeman33 2025-04-02 12:44:43 +07:00 committed by Ferdinand Thiessen
parent 48dc04b571
commit 655ef1031b
No known key found for this signature in database
GPG Key ID: 45FAE7268762B400
8 changed files with 42 additions and 15 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -14,6 +14,8 @@ use OCP\Color;
use OCP\Files\NotFoundException;
use OCP\IAvatar;
use Psr\Log\LoggerInterface;
use OC\User\User;
use OCP\IConfig;
/**
* This class gets and sets users avatars.
@ -84,8 +86,7 @@ abstract class Avatar implements IAvatar {
* @return string
*
*/
protected function getAvatarVector(int $size, bool $darkTheme): string {
$userDisplayName = $this->getDisplayName();
protected function getAvatarVector(string $userDisplayName, int $size, bool $darkTheme): string {
$fgRGB = $this->avatarBackgroundColor($userDisplayName);
$bgRGB = $fgRGB->alphaBlending(0.1, $darkTheme ? new Color(0, 0, 0) : new Color(255, 255, 255));
$fill = sprintf('%02x%02x%02x', $bgRGB->red(), $bgRGB->green(), $bgRGB->blue());
@ -95,10 +96,32 @@ abstract class Avatar implements IAvatar {
return str_replace($toReplace, [$size, $fill, $fgFill, $text], $this->svgTemplate);
}
/**
* Select the rendering font based on the user's display name and language
*/
private function getFont(string $userDisplayName): string {
if (preg_match('/\p{Han}/u', $userDisplayName) === 1) {
$userlang = $this->config->getUserValue($this->user->getUID(), 'core', 'lang', '');
switch ($userlang) {
case 'zh_TW':
return __DIR__ . '/../../../core/fonts/NotoSansTC-Regular.ttf';
case 'zh_HK':
return __DIR__ . '/../../../core/fonts/NotoSansHK-Regular.ttf';
case 'ja':
return __DIR__ . '/../../../core/fonts/NotoSansJP-Regular.ttf';
case 'ko':
return __DIR__ . '/../../../core/fonts/NotoSansKR-Regular.ttf';
default:
return __DIR__ . '/../../../core/fonts/NotoSansSC-Regular.ttf';
}
}
return __DIR__ . '/../../../core/fonts/NotoSans-Regular.ttf';
}
/**
* Generate png avatar from svg with Imagick
*/
protected function generateAvatarFromSvg(int $size, bool $darkTheme): ?string {
protected function generateAvatarFromSvg(string $userDisplayName, int $size, bool $darkTheme): ?string {
if (!extension_loaded('imagick')) {
return null;
}
@ -106,10 +129,11 @@ abstract class Avatar implements IAvatar {
// Avatar generation breaks if RSVG format is enabled. Fall back to gd in that case
if (in_array('RSVG', $formats, true)) {
return null;
}
}
$text = $this->getAvatarText();
try {
$font = __DIR__ . '/../../../core/fonts/NotoSans-Regular.ttf';
$svg = $this->getAvatarVector($size, $darkTheme);
$font = $this->getFont($text);
$svg = $this->getAvatarVector($userDisplayName, $size, $darkTheme);
$avatar = new Imagick();
$avatar->setFont($font);
$avatar->readImageBlob($svg);
@ -151,7 +175,7 @@ abstract class Avatar implements IAvatar {
}
imagefilledrectangle($im, 0, 0, $size, $size, $background);
$font = __DIR__ . '/../../../core/fonts/NotoSans-Regular.ttf';
$font = $this->getFont($text);
$fontSize = $size * 0.4;
[$x, $y] = $this->imageTTFCenter(

@ -87,8 +87,9 @@ class PlaceholderAvatar extends Avatar {
throw new NotFoundException;
}
if (!$data = $this->generateAvatarFromSvg($size, $darkTheme)) {
$data = $this->generateAvatar($this->getDisplayName(), $size, $darkTheme);
$userDisplayName = $this->getDisplayName();
if (!$data = $this->generateAvatarFromSvg($userDisplayName, $size, $darkTheme)) {
$data = $this->generateAvatar($userDisplayName, $size, $darkTheme);
}
try {

@ -26,9 +26,9 @@ class UserAvatar extends Avatar {
public function __construct(
private ISimpleFolder $folder,
private IL10N $l,
private User $user,
protected User $user,
LoggerInterface $logger,
private IConfig $config,
protected IConfig $config,
) {
parent::__construct($logger);
}
@ -201,8 +201,9 @@ class UserAvatar extends Avatar {
try {
$ext = $this->getExtension($generated, $darkTheme);
} catch (NotFoundException $e) {
if (!$data = $this->generateAvatarFromSvg(1024, $darkTheme)) {
$data = $this->generateAvatar($this->getDisplayName(), 1024, $darkTheme);
$userDisplayName = $this->getDisplayName();
if (!$data = $this->generateAvatarFromSvg($userDisplayName, 1024, $darkTheme)) {
$data = $this->generateAvatar($userDisplayName, 1024, $darkTheme);
}
$avatar = $this->folder->newFile($darkTheme ? 'avatar-dark.png' : 'avatar.png');
$avatar->putContent($data);
@ -234,8 +235,9 @@ class UserAvatar extends Avatar {
throw new NotFoundException;
}
if ($generated) {
if (!$data = $this->generateAvatarFromSvg($size, $darkTheme)) {
$data = $this->generateAvatar($this->getDisplayName(), $size, $darkTheme);
$userDisplayName = $this->getDisplayName();
if (!$data = $this->generateAvatarFromSvg($userDisplayName, $size, $darkTheme)) {
$data = $this->generateAvatar($userDisplayName, $size, $darkTheme);
}
} else {
$avatar = new \OCP\Image();