зеркало из https://github.com/mono/ikvm-fork.git
More Sun classes (SwingUtilities2)
This commit is contained in:
Родитель
9a20d46d58
Коммит
5079ec4983
|
@ -160,7 +160,6 @@
|
|||
../../classpath-0.95/java/awt/FlowLayout.java
|
||||
../../classpath-0.95/java/awt/FocusTraversalPolicy.java
|
||||
../../classpath-0.95/java/awt/FontFormatException.java
|
||||
../../classpath-0.95/java/awt/FontMetrics.java
|
||||
../../classpath-0.95/java/awt/Frame.java
|
||||
../../classpath-0.95/java/awt/GradientPaint.java
|
||||
../../classpath-0.95/java/awt/Graphics.java
|
||||
|
@ -254,7 +253,6 @@
|
|||
../../classpath-0.95/java/awt/TextComponent.java
|
||||
../../classpath-0.95/java/awt/TextField.java
|
||||
../../classpath-0.95/java/awt/TexturePaint.java
|
||||
../../classpath-0.95/java/awt/Toolkit.java
|
||||
../../classpath-0.95/java/awt/Transparency.java
|
||||
../../classpath-0.95/java/awt/Window.java
|
||||
../../classpath-0.95/javax/swing/AbstractAction.java
|
||||
|
@ -821,6 +819,7 @@ ikvm/awt/IkvmToolkit.java
|
|||
ikvm/internal/AnnotationAttributeBase.java
|
||||
ikvm/internal/FieldReflectorBase.java
|
||||
java/awt/Font.java
|
||||
java/awt/Toolkit.java
|
||||
java/awt/image/BufferedImage.java
|
||||
java/awt/image/ColorConvertOp.java
|
||||
java/awt/image/IndexColorModel.java
|
||||
|
@ -887,10 +886,12 @@ sun/awt/image/OffScreenImageSource.java
|
|||
sun/awt/image/ShortComponentRaster.java
|
||||
sun/awt/image/SunWritableRaster.java
|
||||
sun/awt/image/ToolkitImage.java
|
||||
sun/font/CompositeFont.java
|
||||
sun/font/Font2D.java
|
||||
sun/font/FontManager.java
|
||||
sun/font/StandardGlyphVector.java
|
||||
sun/font/GlyphLayout.java
|
||||
sun/font/StandardGlyphVector.java
|
||||
sun/font/StrikeCache.java
|
||||
sun/java2d/cmm/lcms/LCMS.java
|
||||
sun/jdbc/odbc/JdbcOdbcCallableStatement.java
|
||||
sun/jdbc/odbc/JdbcOdbcConnection.java
|
||||
|
@ -7353,6 +7354,7 @@ SystemProperties.java
|
|||
../../openjdk6-b16/jdk/src/share/classes/java/awt/font/TextLine.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/java/awt/font/TextMeasurer.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/java/awt/font/TransformAttribute.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/java/awt/FontMetrics.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/java/awt/geom/AffineTransform.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/java/awt/geom/Arc2D.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/java/awt/geom/ArcIterator.java
|
||||
|
@ -9349,11 +9351,16 @@ SystemProperties.java
|
|||
../../openjdk6-b16/jdk/src/share/classes/sun/font/EAttribute.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/ExtendedTextLabel.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/ExtendedTextSourceLabel.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/FontDesignMetrics.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/FontLineMetrics.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/FontResolver.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/FontStrike.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/FontStrikeDesc.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/FontStrikeDisposer.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/GraphicComponent.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/LayoutPathImpl.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/StandardTextSource.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/StrikeMetrics.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/TextLabel.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/TextLabelFactory.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/font/TextLineComponent.java
|
||||
|
@ -10765,11 +10772,13 @@ SystemProperties.java
|
|||
../../openjdk6-b16/jdk/src/share/classes/sun/swing/PrintingStatus.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/swing/StringUIClientPropertyKey.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/swing/SwingLazyValue.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/swing/SwingUtilities2.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/swing/text/CompoundPrintable.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/swing/text/CountingPrintable.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/swing/text/html/FrameEditorPaneTag.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/swing/UIAction.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/swing/UIClientPropertyKey.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/text/CodePointIterator.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/text/CollatorUtilities.java
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/text/CompactByteArray.java
|
||||
|
|
|
@ -618,6 +618,7 @@ assembly.class
|
|||
../../openjdk6-b16/jdk/src/share/classes/java/awt/print/*.class
|
||||
../../openjdk6-b16/jdk/src/share/classes/javax/swing/*.class
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/awt/*.class
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/awt/shell/*.class
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/awt/datatransfer/*.class
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/awt/dnd/*.class
|
||||
../../openjdk6-b16/jdk/src/share/classes/sun/awt/geom/*.class
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Copyright (C) 2009 Volker Berlin (i-net software)
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jeroen Frijters
|
||||
jeroen@frijters.net
|
||||
|
||||
*/
|
||||
package sun.font;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class CompositeFont extends Font2D{
|
||||
|
||||
}
|
|
@ -23,6 +23,9 @@
|
|||
*/
|
||||
package sun.font;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.font.FontRenderContext;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -30,9 +33,26 @@ package sun.font;
|
|||
*/
|
||||
public class Font2D{
|
||||
|
||||
public boolean hasSupplementaryChars(){
|
||||
// TODO Auto-generated method stub
|
||||
/*
|
||||
* All the important subclasses override this which is principally for
|
||||
* the TrueType 'gasp' table.
|
||||
*/
|
||||
public boolean useAAForPtSize(int ptsize) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasSupplementaryChars() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeFromCache(FontStrikeDesc desc){
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public FontStrike getStrike(Font font, FontRenderContext frc){
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,4 +37,19 @@ public class FontManager{
|
|||
return null;
|
||||
}
|
||||
|
||||
public static boolean isComplexText(char[] text, int start, int limit){
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean maybeUsingAlternateCompositeFonts(){
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isNonSimpleChar(char ch){
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package sun.font;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import sun.java2d.Disposer;
|
||||
import sun.misc.Unsafe;
|
||||
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
|
||||
|
||||
/**
|
||||
|
||||
A FontStrike is the keeper of scaled glyph image data which is expensive
|
||||
to compute so needs to be cached.
|
||||
So long as that data may be being used it cannot be invalidated.
|
||||
Yet we also need to limit the amount of native memory and number of
|
||||
strike objects in use.
|
||||
For scaleability and ease of use, a key goal is multi-threaded read
|
||||
access to a strike, so that it may be shared by multiple client objects,
|
||||
potentially executing on different threads, with no special reference
|
||||
counting or "check-out/check-in" requirements which would pass on the
|
||||
burden of keeping track of strike references to the SG2D and other clients.
|
||||
|
||||
A cache of strikes is maintained via Reference objects.
|
||||
This helps in two ways :
|
||||
1. The VM will free references when memory is low or they have not been
|
||||
used in a long time.
|
||||
2. Reference queues provide a way to get notification of this so we can
|
||||
free native memory resources.
|
||||
|
||||
*/
|
||||
|
||||
public final class StrikeCache {
|
||||
|
||||
static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
static ReferenceQueue refQueue = Disposer.getQueue();
|
||||
|
||||
/* Reference objects may have their referents cleared when GC chooses.
|
||||
* During application client start-up there is typically at least one
|
||||
* GC which causes the hotspot VM to clear soft (not just weak) references
|
||||
* Thus not only is there a GC pause, but the work done do rasterise
|
||||
* glyphs that are fairly certain to be needed again almost immediately
|
||||
* is thrown away. So for performance reasons a simple optimisation is to
|
||||
* keep up to 8 strong references to strikes to reduce the chance of
|
||||
* GC'ing strikes that have been used recently. Note that this may not
|
||||
* suffice in Solaris UTF-8 locales where a single composite strike may be
|
||||
* composed of 15 individual strikes, plus the composite strike.
|
||||
* And this assumes the new architecture doesn't maintain strikes for
|
||||
* natively accessed bitmaps. It may be worth "tuning" the number of
|
||||
* strikes kept around for the platform or locale.
|
||||
* Since no attempt is made to ensure uniqueness or ensure synchronized
|
||||
* access there is no guarantee that this cache will ensure that unique
|
||||
* strikes are cached. Every time a strike is looked up it is added
|
||||
* to the current index in this cache. All this cache has to do to be
|
||||
* worthwhile is prevent excessive cache flushing of strikes that are
|
||||
* referenced frequently. The logic that adds references here could be
|
||||
* tweaked to keep only strikes that represent untransformed, screen
|
||||
* sizes as that's the typical performance case.
|
||||
*/
|
||||
static int MINSTRIKES = 8; // can be overridden by property
|
||||
static int recentStrikeIndex = 0;
|
||||
static FontStrike[] recentStrikes;
|
||||
static boolean cacheRefTypeWeak;
|
||||
|
||||
/*
|
||||
* Native sizes and offsets for glyph cache
|
||||
* There are 10 values.
|
||||
*/
|
||||
static int nativeAddressSize;
|
||||
static int glyphInfoSize;
|
||||
static int xAdvanceOffset;
|
||||
static int yAdvanceOffset;
|
||||
static int boundsOffset;
|
||||
static int widthOffset;
|
||||
static int heightOffset;
|
||||
static int rowBytesOffset;
|
||||
static int topLeftXOffset;
|
||||
static int topLeftYOffset;
|
||||
static int pixelDataOffset;
|
||||
static long invisibleGlyphPtr;
|
||||
|
||||
/* Native method used to return information used for unsafe
|
||||
* access to native data.
|
||||
* return values as follows:-
|
||||
* arr[0] = size of an address/pointer.
|
||||
* arr[1] = size of a GlyphInfo
|
||||
* arr[2] = offset of advanceX
|
||||
* arr[3] = offset of advanceY
|
||||
* arr[4] = offset of width
|
||||
* arr[5] = offset of height
|
||||
* arr[6] = offset of rowBytes
|
||||
* arr[7] = offset of topLeftX
|
||||
* arr[8] = offset of topLeftY
|
||||
* arr[9] = offset of pixel data.
|
||||
* arr[10] = address of a GlyphImageRef representing the invisible glyph
|
||||
*/
|
||||
static void getGlyphCacheDescription(long[] infoArray){
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
static {
|
||||
|
||||
long[] nativeInfo = new long[11];
|
||||
getGlyphCacheDescription(nativeInfo);
|
||||
//Can also get address size from Unsafe class :-
|
||||
//nativeAddressSize = unsafe.addressSize();
|
||||
nativeAddressSize = (int)nativeInfo[0];
|
||||
glyphInfoSize = (int)nativeInfo[1];
|
||||
xAdvanceOffset = (int)nativeInfo[2];
|
||||
yAdvanceOffset = (int)nativeInfo[3];
|
||||
widthOffset = (int)nativeInfo[4];
|
||||
heightOffset = (int)nativeInfo[5];
|
||||
rowBytesOffset = (int)nativeInfo[6];
|
||||
topLeftXOffset = (int)nativeInfo[7];
|
||||
topLeftYOffset = (int)nativeInfo[8];
|
||||
pixelDataOffset = (int)nativeInfo[9];
|
||||
invisibleGlyphPtr = nativeInfo[10];
|
||||
if (nativeAddressSize < 4) {
|
||||
throw new InternalError("Unexpected address size for font data: " +
|
||||
nativeAddressSize);
|
||||
}
|
||||
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
|
||||
/* Allow a client to override the reference type used to
|
||||
* cache strikes. The default is "soft" which hints to keep
|
||||
* the strikes around. This property allows the client to
|
||||
* override this to "weak" which hint to the GC to free
|
||||
* memory more agressively.
|
||||
*/
|
||||
String refType =
|
||||
System.getProperty("sun.java2d.font.reftype", "soft");
|
||||
cacheRefTypeWeak = refType.equals("weak");
|
||||
|
||||
String minStrikesStr =
|
||||
System.getProperty("sun.java2d.font.minstrikes");
|
||||
if (minStrikesStr != null) {
|
||||
try {
|
||||
MINSTRIKES = Integer.parseInt(minStrikesStr);
|
||||
if (MINSTRIKES <= 0) {
|
||||
MINSTRIKES = 1;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
recentStrikes = new FontStrike[MINSTRIKES];
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
static void refStrike(FontStrike strike) {
|
||||
int index = recentStrikeIndex;
|
||||
recentStrikes[index] = strike;
|
||||
index++;
|
||||
if (index == MINSTRIKES) {
|
||||
index = 0;
|
||||
}
|
||||
recentStrikeIndex = index;
|
||||
}
|
||||
|
||||
static void disposeStrike(FontStrikeDisposer disposer) {
|
||||
if (disposer.intGlyphImages != null) {
|
||||
freeIntMemory(disposer.intGlyphImages,
|
||||
disposer.pScalerContext);
|
||||
} else if (disposer.longGlyphImages != null) {
|
||||
freeLongMemory(disposer.longGlyphImages,
|
||||
disposer.pScalerContext);
|
||||
} else if (disposer.segIntGlyphImages != null) {
|
||||
/* NB Now making multiple JNI calls in this case.
|
||||
* But assuming that there's a reasonable amount of locality
|
||||
* rather than sparse references then it should be OK.
|
||||
*/
|
||||
for (int i=0; i<disposer.segIntGlyphImages.length; i++) {
|
||||
if (disposer.segIntGlyphImages[i] != null) {
|
||||
freeIntMemory(disposer.segIntGlyphImages[i],
|
||||
disposer.pScalerContext);
|
||||
/* native will only free the scaler context once */
|
||||
disposer.pScalerContext = 0L;
|
||||
disposer.segIntGlyphImages[i] = null;
|
||||
}
|
||||
}
|
||||
/* This may appear inefficient but it should only be invoked
|
||||
* for a strike that never was asked to rasterise a glyph.
|
||||
*/
|
||||
if (disposer.pScalerContext != 0L) {
|
||||
freeIntMemory(new int[0], disposer.pScalerContext);
|
||||
}
|
||||
} else if (disposer.segLongGlyphImages != null) {
|
||||
for (int i=0; i<disposer.segLongGlyphImages.length; i++) {
|
||||
if (disposer.segLongGlyphImages[i] != null) {
|
||||
freeLongMemory(disposer.segLongGlyphImages[i],
|
||||
disposer.pScalerContext);
|
||||
disposer.pScalerContext = 0L;
|
||||
disposer.segLongGlyphImages[i] = null;
|
||||
}
|
||||
}
|
||||
if (disposer.pScalerContext != 0L) {
|
||||
freeLongMemory(new long[0], disposer.pScalerContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void freeIntPointer(int ptr){
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
static void freeLongPointer(long ptr){
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
private static void freeIntMemory(int[] glyphPtrs, long pContext){
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
private static void freeLongMemory(long[] glyphPtrs, long pContext){
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
public static Reference getStrikeRef(FontStrike strike) {
|
||||
return getStrikeRef(strike, cacheRefTypeWeak);
|
||||
}
|
||||
|
||||
public static Reference getStrikeRef(FontStrike strike, boolean weak) {
|
||||
/* Some strikes may have no disposer as there's nothing
|
||||
* for them to free, as they allocated no native resource
|
||||
* eg, if they did not allocate resources because of a problem,
|
||||
* or they never hold native resources. So they create no disposer.
|
||||
* But any strike that reaches here that has a null disposer is
|
||||
* a potential memory leak.
|
||||
*/
|
||||
if (strike.disposer == null) {
|
||||
if (weak) {
|
||||
return new WeakReference(strike);
|
||||
} else {
|
||||
return new SoftReference(strike);
|
||||
}
|
||||
}
|
||||
|
||||
if (weak) {
|
||||
return new WeakDisposerRef(strike);
|
||||
} else {
|
||||
return new SoftDisposerRef(strike);
|
||||
}
|
||||
}
|
||||
|
||||
static interface DisposableStrike {
|
||||
FontStrikeDisposer getDisposer();
|
||||
}
|
||||
|
||||
static class SoftDisposerRef
|
||||
extends SoftReference implements DisposableStrike {
|
||||
|
||||
private FontStrikeDisposer disposer;
|
||||
|
||||
public FontStrikeDisposer getDisposer() {
|
||||
return disposer;
|
||||
}
|
||||
|
||||
SoftDisposerRef(FontStrike strike) {
|
||||
super(strike, StrikeCache.refQueue);
|
||||
disposer = strike.disposer;
|
||||
Disposer.addReference(this, disposer);
|
||||
}
|
||||
}
|
||||
|
||||
static class WeakDisposerRef
|
||||
extends WeakReference implements DisposableStrike {
|
||||
|
||||
private FontStrikeDisposer disposer;
|
||||
|
||||
public FontStrikeDisposer getDisposer() {
|
||||
return disposer;
|
||||
}
|
||||
|
||||
WeakDisposerRef(FontStrike strike) {
|
||||
super(strike, StrikeCache.refQueue);
|
||||
disposer = strike.disposer;
|
||||
Disposer.addReference(this, disposer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -7563,6 +7563,14 @@ namespace IKVM.NativeCode.com.sun.media.sound
|
|||
}
|
||||
}
|
||||
|
||||
namespace IKVM.NativeCode.java.awt
|
||||
{
|
||||
static class FontMetrics
|
||||
{
|
||||
public static void initIDs() { }
|
||||
}
|
||||
}
|
||||
|
||||
namespace IKVM.NativeCode.java.awt.@event
|
||||
{
|
||||
static class InputEvent
|
||||
|
|
Загрузка…
Ссылка в новой задаче