1e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato/*
2e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Copyright (C) 2008 The Android Open Source Project
3e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato *
4e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
5e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * you may not use this file except in compliance with the License.
6e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * You may obtain a copy of the License at
7e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato *
8e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
9e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato *
10e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Unless required by applicable law or agreed to in writing, software
11e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
12e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * See the License for the specific language governing permissions and
14e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * limitations under the License.
15e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato */
16e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
17b10e33ff804a831c71be9303146cea892b9aeb5dJorim Jaggipackage com.android.server.policy;
18e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
19e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.drawable.BitmapDrawable;
20e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.drawable.Drawable;
21e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.drawable.PaintDrawable;
22e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.drawable.StateListDrawable;
23e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.Bitmap;
24e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.BlurMaskFilter;
25e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.Canvas;
26e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.ColorMatrix;
27e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.Paint;
28e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.PaintFlagsDrawFilter;
29e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.PorterDuff;
30e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.Rect;
31e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.graphics.TableMaskFilter;
32e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.util.DisplayMetrics;
3368b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brownimport android.util.TypedValue;
34e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.content.res.Resources;
35e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onoratoimport android.content.Context;
36e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
37e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato/**
38e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato * Various utilities shared amongst the Launcher's classes.
39e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato */
40d09020576f4ae19b006983bc0eab5c317a8856deRubin Xupublic final class IconUtilities {
41e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private static final String TAG = "IconUtilities";
42e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
43e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private static final int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff };
44e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
45e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private int mIconWidth = -1;
46e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private int mIconHeight = -1;
47e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private int mIconTextureWidth = -1;
48e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private int mIconTextureHeight = -1;
49e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
50e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private final Paint mPaint = new Paint();
51e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private final Paint mBlurPaint = new Paint();
52e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private final Paint mGlowColorPressedPaint = new Paint();
53e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private final Paint mGlowColorFocusedPaint = new Paint();
54e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private final Rect mOldBounds = new Rect();
55e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private final Canvas mCanvas = new Canvas();
56e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private final DisplayMetrics mDisplayMetrics;
57e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
58e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private int mColorIndex = 0;
59e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
60e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    public IconUtilities(Context context) {
61e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        final Resources resources = context.getResources();
62e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        DisplayMetrics metrics = mDisplayMetrics = resources.getDisplayMetrics();
63e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        final float density = metrics.density;
64e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        final float blurPx = 5 * density;
65e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
66e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        mIconWidth = mIconHeight = (int) resources.getDimension(android.R.dimen.app_icon_size);
67e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2);
68e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
69e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL));
7068b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown
7168b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown        TypedValue value = new TypedValue();
7268b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown        mGlowColorPressedPaint.setColor(context.getTheme().resolveAttribute(
7368b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown                android.R.attr.colorPressedHighlight, value, true) ? value.data : 0xffffc300);
74e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
7568b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown        mGlowColorFocusedPaint.setColor(context.getTheme().resolveAttribute(
7668b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown                android.R.attr.colorFocusedHighlight, value, true) ? value.data : 0xffff8e00);
77e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
78e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
79e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        ColorMatrix cm = new ColorMatrix();
80e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        cm.setSaturation(0.2f);
81e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
82e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
83e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                Paint.FILTER_BITMAP_FLAG));
84e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    }
85e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
86e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    public Drawable createIconDrawable(Drawable src) {
87e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        Bitmap scaled = createIconBitmap(src);
88e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
89e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        StateListDrawable result = new StateListDrawable();
90e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
91e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        result.addState(new int[] { android.R.attr.state_focused },
92e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                new BitmapDrawable(createSelectedBitmap(scaled, false)));
93e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        result.addState(new int[] { android.R.attr.state_pressed },
94e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                new BitmapDrawable(createSelectedBitmap(scaled, true)));
95e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        result.addState(new int[0], new BitmapDrawable(scaled));
96e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
97e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        result.setBounds(0, 0, mIconTextureWidth, mIconTextureHeight);
98e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        return result;
99e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    }
100e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
101e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    /**
102e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato     * Returns a bitmap suitable for the all apps view.  The bitmap will be a power
103e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato     * of two sized ARGB_8888 bitmap that can be used as a gl texture.
104e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato     */
105d09020576f4ae19b006983bc0eab5c317a8856deRubin Xu    public Bitmap createIconBitmap(Drawable icon) {
106e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        int width = mIconWidth;
107e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        int height = mIconHeight;
108e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
109e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        if (icon instanceof PaintDrawable) {
110e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            PaintDrawable painter = (PaintDrawable) icon;
111e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            painter.setIntrinsicWidth(width);
112e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            painter.setIntrinsicHeight(height);
113e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        } else if (icon instanceof BitmapDrawable) {
114e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            // Ensure the bitmap has a density.
115e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
116e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            Bitmap bitmap = bitmapDrawable.getBitmap();
117e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            if (bitmap.getDensity() == Bitmap.DENSITY_NONE) {
118e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                bitmapDrawable.setTargetDensity(mDisplayMetrics);
119e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            }
120e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        }
121e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        int sourceWidth = icon.getIntrinsicWidth();
122e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        int sourceHeight = icon.getIntrinsicHeight();
123e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
1248108e9f8cd03b97a81dbae83ec7164dcb93b515aSeongJae Park        if (sourceWidth > 0 && sourceHeight > 0) {
125e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            // There are intrinsic sizes.
126e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            if (width < sourceWidth || height < sourceHeight) {
127e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                // It's too big, scale it down.
128e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                final float ratio = (float) sourceWidth / sourceHeight;
129e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                if (sourceWidth > sourceHeight) {
130e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                    height = (int) (width / ratio);
131e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                } else if (sourceHeight > sourceWidth) {
132e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                    width = (int) (height * ratio);
133e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                }
134e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            } else if (sourceWidth < width && sourceHeight < height) {
135e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                // It's small, use the size they gave us.
136e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                width = sourceWidth;
137e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                height = sourceHeight;
138e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            }
139e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        }
140e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
141e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        // no intrinsic size --> use default size
142e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        int textureWidth = mIconTextureWidth;
143e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        int textureHeight = mIconTextureHeight;
144e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
145e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight,
146e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                Bitmap.Config.ARGB_8888);
147e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        final Canvas canvas = mCanvas;
148e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        canvas.setBitmap(bitmap);
149e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
150e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        final int left = (textureWidth-width) / 2;
151e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        final int top = (textureHeight-height) / 2;
152e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
153e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        if (false) {
154e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            // draw a big box for the icon for debugging
155e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            canvas.drawColor(sColors[mColorIndex]);
156e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            if (++mColorIndex >= sColors.length) mColorIndex = 0;
157e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            Paint debugPaint = new Paint();
158e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            debugPaint.setColor(0xffcccc00);
159e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato            canvas.drawRect(left, top, left+width, top+height, debugPaint);
160e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        }
161e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
162e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        mOldBounds.set(icon.getBounds());
163e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        icon.setBounds(left, top, left+width, top+height);
164e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        icon.draw(canvas);
165e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        icon.setBounds(mOldBounds);
166e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
167e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        return bitmap;
168e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    }
169e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
170e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    private Bitmap createSelectedBitmap(Bitmap src, boolean pressed) {
171e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        final Bitmap result = Bitmap.createBitmap(mIconTextureWidth, mIconTextureHeight,
172e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                Bitmap.Config.ARGB_8888);
173e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        final Canvas dest = new Canvas(result);
174e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
175e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        dest.drawColor(0, PorterDuff.Mode.CLEAR);
176e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
177e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        int[] xy = new int[2];
178e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        Bitmap mask = src.extractAlpha(mBlurPaint, xy);
179e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
180e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        dest.drawBitmap(mask, xy[0], xy[1],
181e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato                pressed ? mGlowColorPressedPaint : mGlowColorFocusedPaint);
182e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
183e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        mask.recycle();
184e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
185e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        dest.drawBitmap(src, 0, 0, mPaint);
1866311d0a079702b29984c0d31937345be105e1a5eDianne Hackborn        dest.setBitmap(null);
187e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato
188e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato        return result;
189e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato    }
190e58d1c4e4a03a41c9b8eee6b79304fbf85998d7dJoe Onorato}
191